Javascript 什么是最有效的 node.js 进程间通信库/方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6463945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What's the most efficient node.js inter-process communication library/method?
提问by DuduAlul
We have few node.js processes that should be able to pass messages, What's the most efficient way doing that? How about using node_redis pub/sub
我们很少有 node.js 进程应该能够传递消息,最有效的方法是什么?如何使用 node_redis 发布/订阅
EDIT:the processes might run on different machines
编辑:进程可能在不同的机器上运行
回答by Leonid Beschastny
If you want to send messages from one machine to another and do not care about callbacks then Redis pub/sub is the best solution. It's really easy to implement and Redis is really fast.
如果您想从一台机器向另一台机器发送消息并且不关心回调,那么 Redis 发布/订阅是最好的解决方案。它真的很容易实现,Redis 也非常快。
First you have to install Redis on one of your machines.
首先,您必须在其中一台机器上安装 Redis。
Its really easy to connect to Redis:
连接到Redis真的很容易:
var client = require('redis').createClient(redis_port, redis_host);
But do not forget about opening Redis port in your firewall!
但是不要忘记在防火墙中打开 Redis 端口!
Then you have to subscribe each machine to some channel:
然后你必须为每台机器订阅某个频道:
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
});
You may skip your_namespace
and use global namespace, but you will regret it sooner or later.
你可以跳过your_namespace
并使用全局命名空间,但你迟早会后悔的。
It's really easy to send messages, too:
发送消息也很容易:
var send_message = function(machine_name, message) {
return client.publish("your_namespace:" + machine_name, JSON.stringify(message));
};
If you want to send different kinds of messages, you can use pmessages instead of messages:
如果要发送不同类型的消息,可以使用 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));
};
The best practice is to name your processes (or machines) by their functionality (e.g. 'send_email'
). In that case process (or machine) may be subscribed to more than one channel if it implements more than one functionality.
最佳实践是通过它们的功能(例如'send_email'
)来命名您的进程(或机器)。在这种情况下,如果进程(或机器)实现了多个功能,它可能会订阅多个频道。
Actually, it's possible to build a bi-directional communication using redis. But it's more tricky since it would require to add unique callback channel name to each message in order to receive callback without losing context.
实际上,可以使用 redis 构建双向通信。但它更棘手,因为它需要为每条消息添加唯一的回调通道名称,以便在不丢失上下文的情况下接收回调。
So, my conclusion is this: Use Redis if you need "send and forget" communication, investigate another solutions if you need full-fledged bi-directional communication.
所以,我的结论是:如果您需要“发送和忘记”通信,请使用 Redis,如果您需要成熟的双向通信,请研究另一种解决方案。
回答by Shripad Krishna
Why not use ZeroMQ/0mqfor IPC? Redis (a database) is over-kill for doing something as simple as IPC.
为什么不将ZeroMQ/0mq用于 IPC?Redis(一个数据库)对于做一些像 IPC 这样简单的事情来说太过分了。
Quoting the guide:
引用指南:
?MQ (ZeroMQ, 0MQ, zmq) looks like an embeddable networking library but acts like a concurrency framework. It gives you sockets that carry atomic messages across various transports like in-process, inter-process, TCP, and multicast. You can connect sockets N-to-N with patterns like fanout, pub-sub, task distribution, and request-reply. It's fast enough to be the fabric for clustered products. Its asynchronous I/O model gives you scalable multicore applications, built as asynchronous message-processing tasks.
?MQ (ZeroMQ, 0MQ, zmq) 看起来像一个可嵌入的网络库,但实际上就像一个并发框架。它为您提供了跨各种传输(如进程内、进程间、TCP 和多播)传输原子消息的套接字。您可以使用扇出、发布-订阅、任务分发和请求-回复等模式连接 N 对 N 套接字。它足够快,可以成为集群产品的结构。其异步 I/O 模型为您提供可扩展的多核应用程序,构建为异步消息处理任务。
The advantage of using 0MQ (or even vanilla sockets via net library in Node core, minus all the features provided by a 0MQ socket) is that there is no master process. Its broker-less setup is best fit for the scenario you describe. If you are just pushing out messages to various nodes from one central process you can use PUB/SUB socket in 0mq (also supports IP multicast via PGM/EPGM). Apart from that, 0mq also provides for various different socket types (PUSH/PULL/XREP/XREQ/ROUTER/DEALER) with which you can create custom devices.
使用 0MQ(甚至通过 Node 核心中的网络库使用 vanilla 套接字,减去 0MQ 套接字提供的所有功能)的优点是没有主进程。它的无代理设置最适合您描述的场景。如果您只是从一个中央进程向各个节点推送消息,您可以在 0mq 中使用 PUB/SUB 套接字(也支持通过 PGM/EPGM 的 IP 多播)。除此之外,0mq 还提供了各种不同的套接字类型(PUSH/PULL/XREP/XREQ/ROUTER/DEALER),您可以使用它们来创建自定义设备。
Start with this excellent guide: http://zguide.zeromq.org/page:all
从这个优秀的指南开始:http: //zguide.zeromq.org/page: all
For 0MQ 2.x:
对于 0MQ 2.x:
http://github.com/JustinTulloss/zeromq.node
http://github.com/JustinTulloss/zeromq.node
For 0MQ 3.x (A fork of the above module. This supports PUBLISHER side filtering for PUBSUB):
对于 0MQ 3.x(上述模块的一个分支。这支持 PUBSUB 的 PUBLISHER 端过滤):
回答by morten.c
More than 4 years after the question being ask there is an interprocess communication module called node-ipc. It supports unix/windows sockets for communication on the same machine as well as TCP, TLS and UDP, claiming that at least sockets, TCP and UDP are stable.
在提出问题 4 年多之后,有一个名为node-ipc的进程间通信模块。它支持unix/windows sockets在同一台机器上进行通信以及TCP、TLS和UDP,声称至少sockets、TCP和UDP是稳定的。
Here is a small example taken from the documentation from the github repository:
这是取自 github 存储库文档的一个小示例:
Server for Unix Sockets, Windows Sockets & TCP Sockets
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();
Client for Unix Sockets & TCP Sockets
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);
}
);
}
);
Im currently evaluating this module for a replacement local ipc (but could be remote ipc in the future) as a replacement for an old solution via stdin/stdout. Maybe I will expand my answer when I'm done to give some more information how and how good this module works.
我目前正在评估这个模块以替代本地 ipc(但将来可能是远程 ipc)作为通过 stdin/stdout 替代旧解决方案。也许我会在完成后扩展我的答案,以提供更多信息,该模块如何以及如何工作。
回答by Sagiv Ofek
i would start with the built in functionality that node provide.
you can use process signallinglike:
我将从节点提供的内置功能开始。
您可以使用进程信号,如:
process.on('SIGINT', function () {
console.log('Got SIGINT. Press Control-D to exit.');
});
this signalling
这个信号
Emitted when the processes receives a signal. See sigaction(2) for a list of standard POSIX signal names such as SIGINT, SIGUSR1, etc.
当进程收到信号时发出。有关标准 POSIX 信号名称(例如 SIGINT、SIGUSR1 等)的列表,请参阅 sigaction(2)。
Once you know about process you can spwn a child-processand hook it up to the message
event to retrive and send messages. When using child_process.fork()
you can write to the child using child.send(message, [sendHandle])
and messages are received by a 'message' event on the child.
一旦您了解了进程,您就可以生成一个子进程并将其连接到message
事件以检索和发送消息。使用时,child_process.fork()
您可以写信给孩子使用,child.send(message, [sendHandle])
并且通过孩子上的“消息”事件接收消息。
Also - you can use cluster. The cluster module allows you to easily create a network of processes that all share server ports.
此外 - 您可以使用cluster。集群模块允许您轻松创建所有共享服务器端口的进程网络。
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);
}
For 3rd party services you can check: hook.io, signalsand bean.
回答by Niels
take a look at node-messenger
看看节点信使
https://github.com/weixiyen/messenger.js
https://github.com/weixiyen/messenger.js
will fit most needs easily (pub/sub ... fire and forget .. send/request) with automatic maintained connectionpool
将通过自动维护的连接池轻松满足大多数需求(发布/订阅...触发并忘记...发送/请求)
回答by teleme.io
we are working on multi-process node app, which is required to handle large number of real-time cross-process message.
我们正在开发多进程节点应用程序,需要处理大量实时跨进程消息。
We tried redis-pub-sub first, which failed to meet the requirements.
我们先尝试了redis-pub-sub,没有达到要求。
Then tried tcp socket, which was better, but still not the best.
然后尝试了 tcp socket,这更好,但仍然不是最好的。
So we switched to UDP datagram, that is much faster.
所以我们切换到 UDP 数据报,这要快得多。
Here is the code repo, just a few of lines of code. https://github.com/SGF-Games/node-udpcomm
这是代码仓库,只有几行代码。 https://github.com/SGF-Games/node-udpcomm