javascript - example - ¿Cuál es la biblioteca/método de comunicación entre procesos más eficiente de node.js?
node js communication between processes (6)
¿Por qué no usar ZeroMQ/0mq para IPC? Redis (una base de datos) está sobre-matada por hacer algo tan simple como IPC.
Citando la guía:
ØMQ (ZeroMQ, 0MQ, zmq) parece una biblioteca de red incorporable pero actúa como un marco de concurrencia. Le proporciona sockets que transportan mensajes atómicos a través de diversos transportes como en proceso, entre procesos, TCP y multidifusión. Puede conectar los sockets N a N con patrones como fanout, pub-sub, distribución de tareas y solicitud de respuesta. Es lo suficientemente rápido como para ser el tejido de productos agrupados. Su modelo de E / S asíncrono le brinda aplicaciones de multinúcleo escalables, creadas como tareas asíncronas de procesamiento de mensajes.
La ventaja de usar 0MQ (o incluso sockets de vainilla a través de net library en Node Core, menos todas las características proporcionadas por un socket de 0MQ) es que no hay un proceso maestro. Su configuración sin intermediarios es la mejor opción para el escenario que describe. Si solo está enviando mensajes a varios nodos desde un proceso central, puede usar el socket PUB / SUB en 0 mq (también admite multidifusión IP a través de PGM / EPGM). Aparte de eso, 0mq también proporciona varios tipos de zócalos diferentes (PUSH / PULL / XREP / XREQ / ROUTER / DEALER) con los que puede crear dispositivos personalizados.
Comience con esta excelente guía: http://zguide.zeromq.org/page:all
Para 0MQ 2.x:
http://github.com/JustinTulloss/zeromq.node
Para 0MQ 3.x (una bifurcación del módulo anterior. Esto admite el filtrado lateral de PUBLICADOR para PUBSUB):
Tenemos pocos procesos node.js que deberían poder pasar mensajes. ¿Cuál es la forma más eficiente de hacerlo? ¿Qué hay de usar node_redis pub / sub
EDITAR: los procesos pueden ejecutarse en diferentes máquinas
Comenzaría con la funcionalidad incorporada que proporciona el nodo.
Puede utilizar señalización de proceso como:
process.on(''SIGINT'', function () {
console.log(''Got SIGINT. Press Control-D to exit.'');
});
esta señalización
Se emite cuando el proceso recibe una señal. Consulte sigaction (2) para obtener una lista de nombres de señales POSIX estándar como SIGINT, SIGUSR1, etc.
Una vez que sepa sobre el proceso, puede crear un child-process y conectarlo al evento de message
para recuperar y enviar mensajes. Al usar child_process.fork()
puede escribir al niño usando child.send(message, [sendHandle])
y los mensajes son recibidos por un evento de "mensaje" en el niño.
También - puedes usar cluster . El módulo de clúster le permite crear fácilmente una red de procesos que comparten todos los puertos del servidor.
var cluster = require(''cluster'');
var http = require(''http'');
var numCPUs = require(''os'').cpus().length;
if (cluster.isMaster) {
// Fork workers.
for (var i = 0; i < numCPUs; i++) {
cluster.fork();
}
cluster.on(''exit'', function(worker, code, signal) {
console.log(''worker '' + worker.process.pid + '' died'');
});
} else {
// Workers can share any TCP connection
// In this case its a HTTP server
http.createServer(function(req, res) {
res.writeHead(200);
res.end("hello world/n");
}).listen(8000);
}
Para servicios de terceros puede verificar: hook.io , hook.io y bean .
Estamos trabajando en la aplicación de nodo de proceso múltiple, que se requiere para manejar una gran cantidad de mensajes de proceso cruzado en tiempo real.
Primero probamos redis-pub-sub, que no cumplía con los requisitos.
Luego probé el socket TCP, que era mejor, pero todavía no era el mejor.
Así que cambiamos al datagrama UDP, que es mucho más rápido.
Aquí está el código repo, sólo algunas de las líneas de código. https://github.com/SGF-Games/node-udpcomm
Más de 4 años después de la pregunta, hay un módulo de comunicación entre procesos llamado node-ipc . Admite sockets Unix / Windows para la comunicación en la misma máquina, así como TCP, TLS y UDP, y afirma que al menos los sockets, TCP y UDP son estables.
Aquí hay un pequeño ejemplo tomado de la documentación del repositorio de github:
Servidor para Unix Sockets, Windows Sockets y TCP Sockets
var ipc=require(''node-ipc'');
ipc.config.id = ''world'';
ipc.config.retry= 1500;
ipc.serve(
function(){
ipc.server.on(
''message'',
function(data,socket){
ipc.log(''got a message : ''.debug, data);
ipc.server.emit(
socket,
''message'',
data+'' world!''
);
}
);
}
);
ipc.server.start();
Cliente para Unix Sockets y TCP Sockets
var ipc=require(''node-ipc'');
ipc.config.id = ''hello'';
ipc.config.retry= 1500;
ipc.connectTo(
''world'',
function(){
ipc.of.world.on(
''connect'',
function(){
ipc.log(''## connected to world ##''.rainbow, ipc.config.delay);
ipc.of.world.emit(
''message'',
''hello''
)
}
);
ipc.of.world.on(
''disconnect'',
function(){
ipc.log(''disconnected from world''.notice);
}
);
ipc.of.world.on(
''message'',
function(data){
ipc.log(''got a message from world : ''.debug, data);
}
);
}
);
Actualmente estoy evaluando este módulo para un ipc local de reemplazo (pero podría ser un ipc remoto en el futuro) como reemplazo de una solución antigua a través de stdin / stdout. Tal vez amplíe mi respuesta cuando termine para brindar más información sobre cómo y en qué medida funciona este módulo.
Si desea enviar mensajes de una máquina a otra y no le importan las devoluciones de llamada, Redis pub / sub es la mejor solución. Es muy fácil de implementar y Redis es muy rápido.
Primero tienes que instalar Redis en una de tus máquinas.
Es realmente fácil conectarse a Redis:
var client = require(''redis'').createClient(redis_port, redis_host);
¡Pero no se olvide de abrir el puerto Redis en su firewall!
Luego tienes que suscribir cada máquina a algún canal:
client.on(''ready'', function() {
return client.subscribe(''your_namespace:machine_name'');
});
client.on(''message'', function(channel, json_message) {
var message;
message = JSON.parse(message);
// do whatever you vant with the message
});
Puede omitir su espacio de nombres y usar el espacio de nombres global, pero lo lamentará, tarde o temprano.
También es muy fácil enviar mensajes:
var send_message = function(machine_name, message) {
return client.publish("your_namespace:" + machine_name, JSON.stringify(message));
};
Si desea enviar diferentes tipos de mensajes, puede usar mensajes de texto en lugar de mensajes:
client.on(''ready'', function() {
return client.psubscribe(''your_namespace:machine_name:*'');
});
client.on(''pmessage'', function(pattern, channel, json_message) {
// pattern === ''your_namespace:machine_name:*''
// channel === ''your_namespace:machine_name:''+message_type
var message = JSON.parse(message);
var message_type = channel.split('':'')[2];
// do whatever you want with the message and message_type
});
send_message = function(machine_name, message_type, message) {
return client.publish([
''your_namespace'',
machine_name,
message_type
].join('':''), JSON.stringify(message));
};
La mejor práctica es nombrar sus procesos (o máquinas) por su funcionalidad (p ''send_email''
Ej., ''send_email''
). En ese caso, el proceso (o máquina) se puede suscribir a más de un canal si implementa más de una funcionalidad.
En realidad, es posible construir una comunicación bidireccional usando redis. Pero es más complicado ya que requeriría agregar un nombre de canal de devolución de llamada único a cada mensaje para recibir una devolución de llamada sin perder el contexto.
Por lo tanto, mi conclusión es esta: utilice Redis si necesita una comunicación de "enviar y olvidar", investigue otras soluciones si necesita una comunicación bidireccional completa .
echar un vistazo a nodo-mensajero
https://github.com/weixiyen/messenger.js
se ajustará a la mayoría de las necesidades fácilmente (pub / sub ... dispara y olvida .. enviar / solicitar) con conexión automática mantenida