-->

结合的Node.js和Python(Combining node.js and Python)

2019-06-24 20:46发布

Node.js的是我们的web项目的完美匹配,但也有我们宁愿Python的一些计算任务。 我们也已经为他们Python代码。 我们高度关注的速度,什么是最优雅的方式如何调用从node.js的一个Python“工人”在异步非阻塞的方式吗?

Answer 1:

于Node.js和Python服务器之间的通信,如果两个进程在同一台服务器和TCP / IP套接字上运行,否则我会使用Unix套接字。 用于编组协议我会采取JSON或协议缓冲器 。 如果线程的Python显示出来成为一个瓶颈,可以考虑使用扭曲的Python ,它提供了相同的事件驱动并发性做node.js中

如果你喜欢冒险,学习的Clojure ( clojurescript , Clojure的-PY ),你会得到运行,并与基于Java,JavaScript的(node.js的在内),CLR和Python代码存在的互操作相同的语言。 而你只需要使用Clojure的数据结构得到极好的编组协议。



Answer 2:

这听起来像一个场景zeroMQ将是一个不错的选择。 这是一个消息框架,它类似于使用TCP或Unix套接字,但它更强大( http://zguide.zeromq.org/py:all )

有使用zeroMQ提供一个RPC框架,非常有效的库。 这就是所谓的zeroRPC( http://www.zerorpc.io/ )。 这里是世界你好。

Python的 “你好X” 服务器:

import zerorpc

class HelloRPC(object):
    '''pass the method a name, it replies "Hello name!"'''
    def hello(self, name):
        return "Hello, {0}!".format(name)

def main():
    s = zerorpc.Server(HelloRPC())
    s.bind("tcp://*:4242")
    s.run()

if __name__ == "__main__" : main()

和Node.js的客户:

var zerorpc = require("zerorpc");

var client = new zerorpc.Client();
client.connect("tcp://127.0.0.1:4242");
//calls the method on the python object
client.invoke("hello", "World", function(error, reply, streaming) {
    if(error){
        console.log("ERROR: ", error);
    }
    console.log(reply);
});

反之亦然,Node.js的服务器:

var zerorpc = require("zerorpc");

var server = new zerorpc.Server({
    hello: function(name, reply) {
        reply(null, "Hello, " + name, false);
    }
});

server.bind("tcp://0.0.0.0:4242");

和Python客户端

import zerorpc, sys

c = zerorpc.Client()
c.connect("tcp://127.0.0.1:4242")
name = sys.argv[1] if len(sys.argv) > 1 else "dude"
print c.hello(name)


Answer 3:

如果你安排在一个单独的进程你的Python工人(无论是长时间运行的服务器类型的进程或需求催生的孩子),有了它你的沟通将会对Node.js的端异步。 UNIX / TCP套接字和标准输入/输出/ ERR通信本质上是异步的节点。



Answer 4:

我还考虑阿帕奇节俭http://thrift.apache.org/

它可以几种编程语言之间的桥梁,是高效并具有异步或同步调用的支持。 查看完整的功能在这里http://thrift.apache.org/docs/features/

多语言可以为未来的计划非常有用,例如,如果你以后想要做的在C计算任务的一部分++这是很容易做到的它添加到使用节俭的组合。



Answer 5:

我已经使用了大量成功的thoonk.js沿thoonk.py 。 Thoonk利用Redis的(内存键值存储)给你喂(认为发布/订阅)进行通信,队列和工作模式。

这是为什么比Unix套接字或直接TCP套接字更好? 整体性能可能会下降一点点,但是Thoonk提供了可简化不必手动与插座处理一个非常简单的API。 Thoonk也有助于使它真正容易实现分布式计算模型,它允许你扩展你的Python工人以提高性能,因为你只旋转了新的情况下,你的Python工人的,并将它们连接到同一个redis的服务器。



Answer 6:

我建议你使用使用一些工作队列,例如优秀的Gearman ,这将为您提供调度后台作业的好方法,并异步一旦他们处理得到他们的结果。

这样做的好处,在Digg的大量使用(其中许多人)是它提供了一个强大的,可扩展的和可靠的方法,使员工在任何语言中的任何语言与客户说话。



Answer 7:

更新2019

有几种方法来实现这一点,这里是复杂的顺序增加列表

  1. Python Shell中,你会写流蟒蛇控制台,它会写回你
  2. Redis的酒吧子,你可以在你的节点JS出版商推数据有一个通道在Python听
  3. 其中节点充当客户端和Python充当服务器或反之亦然WebSocket连接
  4. 与快递/瓶/龙卷风等暴露为其他查询的API端点分开工作API连接

方法1 Python Shell中最简单的方法

source.js文件

const ps = require('python-shell')
// very important to add -u option since our python script runs infinitely
var options = {
    pythonPath: '/Users/zup/.local/share/virtualenvs/python_shell_test-TJN5lQez/bin/python',
    pythonOptions: ['-u'], // get print results in real-time
    // make sure you use an absolute path for scriptPath
    scriptPath: "./subscriber/",
    // args: ['value1', 'value2', 'value3'],
    mode: 'json'
};

const shell = new ps.PythonShell("destination.py", options);

function generateArray() {
    const list = []
    for (let i = 0; i < 1000; i++) {
        list.push(Math.random() * 1000)
    }
    return list
}

setInterval(() => {
    shell.send(generateArray())
}, 1000);

shell.on("message", message => {
    console.log(message);
})

destination.py文件

import datetime
import sys
import time
import numpy
import talib
import timeit
import json
import logging
logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)

size = 1000
p = 100
o = numpy.random.random(size)
h = numpy.random.random(size)
l = numpy.random.random(size)
c = numpy.random.random(size)
v = numpy.random.random(size)

def get_indicators(values):
    # Return the RSI of the values sent from node.js
    numpy_values = numpy.array(values, dtype=numpy.double) 
    return talib.func.RSI(numpy_values, 14)

for line in sys.stdin:
    l = json.loads(line)
    print(get_indicators(l))
    # Without this step the output may not be immediately available in node
    sys.stdout.flush()

注意 :请一个文件夹被叫用户是在同一水平source.js文件,并把destination.py里面。 不要忘记改变你的virtualenv环境



文章来源: Combining node.js and Python