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

我们只有少数应该能够传递消息的node.js进程,最有效的方法是什么?如何使用node_redis发布/订阅

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

DuduAlul asked 2019-11-17T01:37:17Z
6个解决方案
42 votes

如果您希望将消息从一台计算机发送到另一台计算机,并且不关心回调,那么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
});

您可以跳过'send_email'并使用全局名称空间,但迟早会感到遗憾。

发送消息也很容易:

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;如果需要全面的双向通信,请研究其他解决方案。

Leonid Beschastny answered 2019-11-17T01:38:36Z
33 votes

为什么不对IPC使用ZeroMQ / 0mq? Redis(数据库)在做像IPC这样简单的事情时显得过分杀人。

引用指南:

ØMQ(ZeroMQ,0MQ,zmq)看起来像一个可嵌入的网络库   但就像一个并发框架。 它为您提供了随身携带的插座   跨各种传输方式的原子消息,例如过程中,   进程间,TCP和多播。 您可以将N-to-N插座与   扇出,发布-订阅,任务分配和请求-回复等模式。   它足够快,可以成为集群产品的基础。 它的   异步I / O模型为您提供了可扩展的多核应用程序,   构建为异步消息处理任务。

使用0MQ(甚至通过Node核心中的网络库的普通套接字,减去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侧过滤):

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

Shripad Krishna answered 2019-11-17T01:39:56Z
31 votes

提出问题后的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的旧解决方案。 也许我会在完成后扩展我的答案,以提供更多有关此模块的工作方式和效果的信息。

morten.c answered 2019-11-17T01:40:48Z
8 votes

我将从节点提供的内置功能开始。
您可以使用过程信令,例如:

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

这个信号

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

了解进程后,您可以创建一个子进程并将其挂接到message事件以检索和发送消息。 使用child_process.fork()时,您可以使用child.send(message, [sendHandle])向孩子写信,并且孩子上的“消息”事件会收到消息。

另外-您可以使用群集。 群集模块使您可以轻松创建所有共享服务器端口的进程网络。

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。

Sagiv Ofek answered 2019-11-17T01:41:53Z
2 votes

看看节点信使

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

具有自动维护的连接池,可以轻松满足大多数需求(发布/订阅...失火..发送/请求)

Niels answered 2019-11-17T01:42:31Z
1 votes

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

我们首先尝试了redis-pub-sub,但没有达到要求。

然后尝试使用tcp套接字,虽然更好,但仍然不是最好的。

因此,我们切换到UDP数据报,这要快得多。

这是代码库,仅几行代码。[https://github.com/SGF-Games/node-udpcomm]

teleme.io answered 2019-11-17T01:43:24Z
translate from https://stackoverflow.com:/questions/6463945/whats-the-most-efficient-node-js-inter-process-communication-library-method