Комбинирующий узел.js и Python


узел.js идеально подходит для нашего веб-проекта, но есть несколько вычислительных задач, для которых мы предпочли бы Python. У нас также уже есть код Python для них. Мы очень обеспокоены скоростью, что является самым элегантным способом, как назвать Python "рабочий" из узла.js в асинхронном неблокирующем режиме?

6 116

6 ответов:

для связи между узлами.JS и Python server, я бы использовал сокеты Unix, если оба процесса работают на одном сервере и сокеты TCP/IP в противном случае. Для протокола маршалинга я бы взял JSON или буфера протокола. Если резьбовой Python оказывается узким местом, рассмотрите возможность использования Витая Питона, которым обеспечивает тот же управляемый событиями параллелизм, что и узел do.js.

Если вы чувствуете приключений, узнать clojure (clojurescript,clojure-py) и вы получите тот же язык, который работает и взаимодействует с существующим кодом на Java, JavaScript (node.JS включены), CLR и Python. И вы получаете превосходный протокол маршалинга, просто используя структуры данных clojure.

Это звучит как сценарий, где zeroMQ будет хорошо подходят. Это платформа обмена сообщениями, которая похожа на использование сокетов TCP или Unix, но она гораздо более надежна (http://zguide.zeromq.org/py:all)

есть библиотека, которая использует zeroMQ, чтобы обеспечить структуру RPC, которая работает довольно хорошо. Это называется zeroRPC (http://www.zerorpc.io/). Вот Привет мир.

Python" Hello x " server:

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()

и узел.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);
});

или наоборот, узел.сервер 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)

Если вы организуете свой рабочий Python в отдельном процессе (либо длительном процессе типа сервера, либо порожденном дочернем по требованию), ваше общение с ним будет асинхронным на узле.Яш стороны. Сокеты UNIX / TCP и связь stdin/out/err по своей сути асинхронны в узле.

Я бы также рассмотрел Apache Thrift http://thrift.apache.org/

Он может соединяться между несколькими языками программирования, является высокоэффективным и имеет поддержку асинхронных или синхронизирующих вызовов. Смотрите полные возможности здесь http://thrift.apache.org/docs/features/

мультиязык может быть полезен для будущих планов, например, если вы позже захотите сделать часть вычислительной задачи на C++, очень легко добавить ее в микс, используя бережливость.

Я имел большой успех, используя Тун.js вместе с thoonk.py. Thoonk использует Redis (in-memory key-value store), чтобы дать вам фид (думаю, публиковать/подписываться), очереди и шаблоны заданий для связи.

Почему это лучше, чем сокеты unix или прямые сокеты tcp? Общая производительность может быть немного снижена, однако Thoonk предоставляет очень простой API, который упрощает ручную работу с сокетом. Thoonk также помогает сделать это действительно тривиально реализовать распределенную вычислительную модель, которая позволяет масштабировать ваши рабочие python для повышения производительности, так как вы просто запускаете новые экземпляры ваших рабочих python и подключаете их к тому же серверу redis.

Я бы рекомендовал использовать некоторую рабочую очередь, используя, например, отличный Gearman, который предоставит вам отличный способ отправки фоновых заданий и асинхронно получать их Результат после их обработки.

преимущество этого, широко используемого в Digg (среди многих других), заключается в том, что он обеспечивает сильный, масштабируемый и надежный способ заставить работников на любом языке разговаривать с клиентами на любом языке.