什么是最有效的node.js进程间通信库/方法?

我们有几个node.js进程应该能够传递消息,那么最有效的方法是什么? 如何使用node_redis pub / sub

编辑:进程可能运行在不同的机器上

如果您想将消息从一台机器发送到另一台机器,而不关心callback,那么Redis pub / sub是最好的解决scheme。 这很容易实现,而且Redis真的很快。

首先,您必须在其中一台机器上安装Redis。

它很容易连接到Redis:

var client = require('redis').createClient(redis_port, redis_host); 

但是别忘了在防火墙中打开Redis端口!

那么你必须订阅每台机器到某个频道:

 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 }); 

您可以跳过your_namespace并使用全局名称空间,但迟早会后悔的。

发送消息也非常简单:

 var send_message = function(machine_name, message) { return client.publish("your_namespace:" + machine_name, JSON.stringify(message)); }; 

如果你想发送不同types的消息,你可以使用pmessages而不是消息:

 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)); }; 

最好的做法是通过它们的function来命名你的进程(或机器)(例如'send_email' )。 在这种情况下,如果进程(或机器)实现了多个function,则可以订阅多个通道。

实际上,使用redisbuild立双向通信是可能的。 但它更棘手,因为它需要添加唯一的callback通道名称到每个消息,以接收callback而不丢失上下文。

所以,我的结论是: 如果您需要“发送和忘记”通信,请使用Redis,如果您需要全面的双向通信,请调查另一种解决scheme

为什么不把ZeroMQ / 0mq用于IPC? Redis(一个数据库)因为像IPC这样简单的事情而被过度杀死。

引用指南:

ØMQ(ZeroMQ,0MQ,zmq)看起来像一个可embedded的networking库,但是像一个并发框架。 它给你提供了跨越各种传输(如进程内,进程间,TCP和多播)的primefaces消息的套接字。 您可以将套接字N对N连接到fanout,pub-sub,任务分配和请求回复等模式。 成为集群产品的结构已经足够快了。 其asynchronousI / O模型为您提供可扩展的多核应用程序,构build为asynchronous消息处理任务。

使用0MQ(甚至是通过Node核心网库的vanilla套接字,减去0MQ套接字提供的所有function)的优点是没有主进程。 它的经纪人设置最适合你描述的场景。 如果您只是从一个中央处理器向各个节点推送消息,则可以使用0mq中的PUB / SUB套接字(也支持通过PGM / EPGM的IP多播)。 除此之外,0mq还提供了各种不同的套接字types(PUSH / PULL / XREP / XREQ / ROUTER / DEALER),您可以使用它们创build自定义设备。

从这个优秀的指南开始:http: //zguide.zeromq.org/page : all

对于0MQ 2.x:

http://github.com/JustinTulloss/zeromq.node

对于0MQ 3.x(上述模块的一个分支,这支持PUBSUB的PUBLISHER侧过滤):

http://github.com/shripadk/zeromq.node

问题提出四年多以后,有一个名为node-ipc的进程间通信模块。 它支持在同一台机器上进行通信的unix / windows套接字以及TCP,TLS和UDP,声称至lesssocket,TCP和UDP是稳定的。

下面是一个从github仓库的文档中取得的小例子:

服务器的Unix套接字,Windows套接字和TCP套接字

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

Unix套接字和TCP套接字的客户端

 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); } ); } ); 

我目前正在评估这个模块的替代本地ipc(但可能是远程ipc在未来)作为替代旧的解决scheme通过stdin /标准输出。 也许我会扩大我的答案,当我完成了一些更多的信息,这个模块的工作原理。

我将从节点提供的内置function开始。
你可以使用过程信号如:

 process.on('SIGINT', function () { console.log('Got SIGINT. Press Control-D to exit.'); }); 

这个信号

当进程收到信号时发出。 有关标准POSIX信号名称(如SIGINT,SIGUSR1等)的列表,请参阅sigaction(2)。

一旦你了解了进程,你就可以调用一个subprocess,并将其挂接到message事件中来回顾并发送消息。 当使用child_process.fork()你可以使用child.send(message, [sendHandle])写给孩子child.send(message, [sendHandle])并通过孩子上的'message'事件接收消息。

另外 – 你可以使用群集 。 群集模块允许您轻松创build全部共享服务器端口的进程networking。

 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); } 

对于第三方服务,您可以检查: hook.io , 信号和bean 。

看看Node-Messenger

https://github.com/weixiyen/messenger.js

将容易满足大多数需求(酒吧/子…火,忘记..发送/请求)与自动维护连接池

我们正在开发多进程节点应用程序,这是处理大量实时跨进程消息所必需的。

我们首先尝试了redis-pub-sub,这不符合要求。

然后尝试TCP套接字,这是更好的,但仍然不是最好的。

所以我们切换到UDP数据报,这是更快。

这里是代码回购,只是几行代码。 https://github.com/SGF-Games/node-udpcomm