example - Combinando node.js y Python
node js python example (6)
Node.js es una combinación perfecta para nuestro proyecto web, pero hay pocas tareas computacionales para las cuales preferiríamos Python. También tenemos un código Python para ellos. Estamos muy preocupados por la velocidad, ¿cuál es la forma más elegante de llamar a un "trabajador" de Python desde node.js de forma asíncrona y sin bloqueo?
Para la comunicación entre node.js y el servidor de Python, usaría sockets de Unix si ambos procesos se ejecutan en el mismo servidor y en los sockets de TCP / IP de lo contrario. Para el protocolo de cálculo de referencias, tomaría JSON o el buffer del protocolo . Si el Python con hebras aparece como un cuello de botella, considere usar Twisted Python , que proporciona la misma concurrencia impulsada por eventos que nodePoint.js.
Si te sientes aventurero, aprende clojure ( clojurescript , clojure-py ) y obtendrás el mismo lenguaje que se ejecuta e interopera con el código existente en Java, JavaScript (node.js incluido), CLR y Python. Y obtienes un excelente protocolo de clasificación simplemente usando las estructuras de datos de clojure.
Recomiendo usar alguna cola de trabajo usando, por ejemplo, el excelente Gearman , que le proporcionará una excelente manera de enviar trabajos en segundo plano y obtener de forma asíncrona su resultado una vez que se procesen.
La ventaja de esto, utilizada en gran medida en Digg (entre muchos otros) es que proporciona una forma sólida, escalable y sólida para que los trabajadores en cualquier idioma hablen con los clientes en cualquier idioma.
Si organiza su Python Worker en un proceso separado (ya sea un proceso de tipo servidor de larga ejecución o un elemento secundario bajo demanda), su comunicación con él será asincrónica en el lado node.js. Los sockets UNIX / TCP y la comunicación stdin / out / err son intrínsecamente asincrónicos en el nodo.
También consideraría Apache Thrift http://thrift.apache.org/
Puede tender puentes entre varios lenguajes de programación, es altamente eficiente y tiene soporte para llamadas asincrónicas o sincronizadas. Vea las características completas aquí http://thrift.apache.org/docs/features/
El lenguaje múltiple puede ser útil para planes futuros, por ejemplo, si luego desea realizar una parte de la tarea computacional en C ++, es muy fácil agregarla a la mezcla con Thrift.
Tuve mucho éxito al utilizar thoonk.js junto con thoonk.py . Thoonk aprovecha Redis (tienda de valores-clave en memoria) para proporcionarle alimentación (piense en publicar / suscribir), cola y patrones de trabajo para la comunicación.
¿Por qué es esto mejor que los zócalos de Unix o los zócalos de tcp directos? El rendimiento general puede reducirse un poco, sin embargo Thoonk proporciona una API realmente simple que simplifica tener que lidiar manualmente con un socket. Thoonk también ayuda a que sea realmente trivial implementar un modelo de computación distribuida que le permita escalar a sus trabajadores python para aumentar el rendimiento, ya que simplemente activa nuevas instancias de sus trabajadores python y los conecta al mismo servidor redis.
Esto suena como un escenario donde zeroMQ sería una buena opción. Es un marco de mensajería que es similar al uso de sockets TCP o Unix, pero es mucho más robusto ( http://zguide.zeromq.org/py:all )
Hay una biblioteca que usa zeroMQ para proporcionar un marco RPC que funciona bastante bien. Se llama zeroRPC ( http://www.zerorpc.io/ ). Aquí está el mundo de hola.
Servidor Python "Hello 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()
Y el cliente 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);
});
O viceversa, servidor 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");
Y el cliente de 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)