web-dev-qa-db-ja.com

最も効率的なnode.jsプロセス間通信ライブラリ/メソッドは何ですか?

メッセージを渡すことができるnode.jsプロセスはほとんどありません。これを行う最も効率的な方法は何ですか? node_redis pub/subの使用方法はどうですか

編集:プロセスは異なるマシンで実行される可能性があります

54
DuduAlul

あるマシンから別のマシンにメッセージを送信し、コールバックを気にしない場合は、Redis pub/subが最適なソリューションです。実装は非常に簡単で、Redisは非常に高速です。

まず、マシンの1つに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を使用し、本格的な双方向通信が必要な場合は別のソリューションを調査します

42

IPCに ZeroMQ/0mq を使用しないのはなぜですか? Redis(データベース)は、IPCのような単純なことを行うのはやり過ぎです。

ガイドを引用:

ØMQ(ZeroMQ、0MQ、zmq)は埋め込み可能なネットワークライブラリのように見えますが、同時実行フレームワークのように機能します。インプロセス、プロセス間、TCP、マルチキャストなどのさまざまなトランスポートでアトミックメッセージを運ぶソケットを提供します。ソケットをファンアウト、pub-sub、タスク分散、要求応答などのパターンでN対Nに接続できます。クラスター製品のファブリックになるのに十分な速さです。非同期I/Oモデルは、非同期メッセージ処理タスクとして構築されたスケーラブルなマルチコアアプリケーションを提供します。

0MQ(またはNodeコア、0MQソケットが提供するすべての機能を除く)のネットライブラリ経由のバニラソケット)を使用する利点は、マスタープロセスがないことです。 1つの中央プロセスからさまざまなノードにメッセージをプッシュするだけの場合、0mqでPUB/SUBソケットを使用できます(PGM/EPGMを介したIPマルチキャストもサポートします)。カスタムデバイスを作成できるさまざまなソケットタイプ(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

33
Shripad Krishna

質問されてから4年以上が経過した後、 node-ipc と呼ばれるプロセス間通信モジュールがあります。 TCP、TLS、UDPと同様に、同じマシン上での通信用のUNIX/Windowsソケットをサポートし、少なくともソケットTCPおよびUDPは安定していると主張しています。

Githubリポジトリのドキュメントから抜粋した小さな例を次に示します。

Unixソケット、Windowsソケット用サーバー&TCP Sockets

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 Sockets

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

現在、stdin/stdoutを介した古いソリューションの代替として、このモジュールを代替ローカルipc(ただし、将来はリモートipcになる可能性がある)として評価しています。このモジュールがどのように、そしてどのように機能するかについて、さらに情報を提供するために終わったら、答えを拡大するでしょう。

31
morten.c

私は、ノードが提供する組み込み機能から始めます。
次のように使用できます process signalling like:

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

このシグナリング

プロセスがシグナルを受信したときに生成されます。 SIGINT、SIGUSR1などの標準POSIXシグナル名のリストについては、sigaction(2)を参照してください。

プロセスについて知ると、 child-process を生成し、messageイベントにフックして、メッセージを取得して送信できます。 child_process.fork()を使用する場合、child.send(message, [sendHandle])を使用して子に書き込むことができ、メッセージは子の 'message'イベントによって受信されます。

また、 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);
}
_

サードパーティのサービスについては、 hook.iosignals 、および bean を確認できます。

8
Sagiv Ofek

ノードメッセンジャーを見てください

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

ほとんどのニーズに簡単に適合します(pub/sub ... fire and forget .. send/request)。

2
Niels

多数のリアルタイムのクロスプロセスメッセージを処理するために必要なマルチプロセスノードアプリに取り組んでいます。

最初にredis-pub-subを試しましたが、要件を満たせませんでした。

その後、tcpソケットを試してみました。これは優れていましたが、それでも最高ではありませんでした。

そのため、UDPデータグラムに切り替えました。これははるかに高速です。

ここにコードレポがあります、ほんの数行のコードです。 https://github.com/SGF-Games/node-udpcomm

1
teleme.io