[英]What's the most efficient node.js inter-process communication library/method?
我们有几个node.js进程应该能够传递消息,这样做最有效的方法是什么? 如何使用node_redis pub / sub
编辑:进程可能在不同的机器上运行
如果您想将消息从一台机器发送到另一台机器并且不关心回调,那么Redis pub / sub是最佳解决方案。 它实现起来非常简单,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));
};
如果要发送不同类型的消息,可以使用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));
};
最佳实践是根据其功能命名您的流程(或机器)(例如'send_email'
)。 在这种情况下,如果进程(或机器)实现多个功能,则它可以订阅多个通道。
实际上,可以使用redis构建双向通信。 但它更棘手,因为它需要为每条消息添加唯一的回调通道名称,以便在不丢失上下文的情况下接收回调。
因此,我的结论是: 如果您需要“发送并忘记”通信,请使用Redis,如果您需要完全成熟的双向通信,请研究其他解决方案 。
为什么不将ZeroMQ / 0mq用于IPC? Redis(一个数据库)因为做一些像IPC那样简单的事情而被过度杀戮。
引用指南:
ØMQ(ZeroMQ,0MQ,zmq)看起来像一个可嵌入的网络库,但就像一个并发框架。 它为您提供了在各种传输中传输原子消息的套接字,如进程内,进程间,TCP和多播。 您可以使用扇出,发布 - 订阅,任务分发和请求 - 回复等模式连接N到N的套接字。 它足够快,可以成为集群产品的结构。 其异步I / O模型为您提供可扩展的多核应用程序,构建为异步消息处理任务。
使用0MQ(甚至通过Node核心中的网络库的vanilla套接字,减去0MQ套接字提供的所有功能)的优点是没有主进程。 其无代理设置最适合您描述的场景。 如果您只是从一个中央进程向各个节点推送消息,则可以在0mq中使用PUB / SUB套接字(也支持通过PGM / EPGM进行IP多播)。 除此之外,0mq还提供各种不同的套接字类型(PUSH / PULL / XREP / XREQ / ROUTER / DEALER),您可以使用它们创建自定义设备。
从这本优秀的指南开始:http: //zguide.zeromq.org/page : all
对于0MQ 2.x:
http://github.com/JustinTulloss/zeromq.node
对于0MQ 3.x(上述模块的一个分支。这支持PUBSUB的PUBLISHER侧过滤):
在询问问题超过4年后,有一个名为node-ipc的进程间通信模块。 它支持unix / windows套接字,用于在同一台机器上进行通信,以及TCP,TLS和UDP,声称至少套接字,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)作为stdin / stdout的旧解决方案的替代品。 也许我会在完成这个模块的工作原理时提供更多信息,以扩展我的答案。
我将从节点提供的内置功能开始。
您可以使用以下流程信令 :
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});
这个信号
当进程收到信号时发出。 有关标准POSIX信号名称列表,请参阅sigaction(2),例如SIGINT,SIGUSR1等。
一旦了解了进程,就可以创建一个子进程,并将其连接到message
事件以进行反向和发送消息。 使用child_process.fork()
您可以使用child.send(message, [sendHandle])
写入子项child.send(message, [sendHandle])
并通过子项上的“message”事件接收消息。
此外 - 您可以使用群集 。 群集模块允许您轻松创建所有共享服务器端口的进程网络。
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);
}
看看node-messenger
https://github.com/weixiyen/messenger.js
通过自动维护的连接池,可以轻松满足大多数需求(发布/发布...触发并忘记发送/请求)
我们正在研究多进程节点应用程序,它需要处理大量的实时跨进程消息。
我们首先尝试了redis-pub-sub,但未能满足要求。
然后尝试了tcp socket,这是更好的,但仍然不是最好的。
所以我们切换到UDP数据报,这要快得多。
这是代码仓库,只是几行代码。 https://github.com/SGF-Games/node-udpcomm
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.