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

2019-05-13 09:10发布

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

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

Answer 1:

如果你想从一台计算机发送消息到另一个不关心回调然后Redis的发布/订阅是最佳的解决方案。 这真的很容易实现和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的,如果你需要“发送和忘记”沟通,调查溶液彼此相互如果你需要全面的双向通信



Answer 2:

为什么不使用ZeroMQ / 0mq的IPC? Redis的(数据库)是过度杀做的IPC这样简单的事情。

引用手册:

ØMQ(ZeroMQ,0MQ,ZMQ)看起来像一个嵌入式的网络库,但就像一个并发框架。 它可以让你携带像进程,进程间,TCP和组播在各种交通工具原子信息插座。 你可以像扇出,发布 - 订阅,任务分配,并请求 - 应答模式的连接插座N对-N。 它的速度不够快是面料集群产品。 它的异步I / O模型提供了可扩展的多核应用程序,内置的异步消息处理任务。

使用0MQ的优点(通过节点核心网库或甚至香草插座,减去由0MQ插座提供的所有功能)是没有主过程。 其经纪人少的设置是您所描述的场景最合适的。 如果你只是从一个中央工艺推出邮件发送到不同的节点,你可以在0mq使用的pub / sub插座(也可通过PGM / EPGM支持IP多播)。 除此之外,0mq还提供了各种不同的套接字类型(推/拉/ XREP / XREQ /路由器/经销商),您可以创建自定义的设备。

开始与这个优秀导游: http://zguide.zeromq.org/page:all

对于0MQ 2.X:

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

对于0MQ 3.X(上述模块的叉这支持用于发布订阅PUBLISHER侧滤波):

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



Answer 3:

4年以上问题的存在后,问有一个叫做进程间通信模块节点-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)作为用于通过标准输入/输出的旧溶液的替代品。 也许我会扩大我的答案时,我做给一些更多的信息,这个模块怎么怎么样好作品。



Answer 4:

我将与内置的功能,节点提供启动。
你可以使用过程中的信令 ,如:

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

这个信号

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

一旦你了解的过程,你可以spwn一个子进程 ,并把它挂到的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 , 信号和豆类 。



Answer 5:

看看节点信使

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

将适合最容易需要(发布/订阅...射后不理..发送/请求)具有自动保持连接池



Answer 6:

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

我们试图Redis的-PUB-SUB第一,它未能满足要求。

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

因此,我们切换到UDP数据包,也就是要快得多。

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



文章来源: What's the most efficient node.js inter-process communication library/method?