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
有几种方法来实现这一点,这里是复杂的顺序增加列表
- Python Shell中,你会写流蟒蛇控制台,它会写回你
- Redis的酒吧子,你可以在你的节点JS出版商推数据有一个通道在Python听
- 其中节点充当客户端和Python充当服务器或反之亦然WebSocket连接
- 与快递/瓶/龙卷风等暴露为其他查询的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环境