Какая наиболее эффективная библиотека/метод взаимодействия между процессами node.js?

У нас мало процессов node.js, которые должны иметь возможность передавать сообщения, Какой самый эффективный способ сделать это? Как насчет использования node_redis pub/sub

EDIT: процессы могут выполняться на разных машинах

Ответ 1

Если вы хотите отправлять сообщения с одной машины на другую и не заботиться о обратных вызовах, то 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, если вам нужно "отправить и забыть" сообщение, исследуйте другие решения, если вам нужна полноценная двунаправленная связь.

Ответ 2

Почему бы не использовать ZeroMQ/0mq для IPC? Redis (база данных) слишком много убивает, делая что-то столь же простое, как IPC.

Цитирование руководства:

ØMQ (ZeroMQ, 0MQ, zmq) выглядит как встраиваемая сетевая библиотека но действует как структура concurrency. Это дает вам гнезда, которые несут атомных сообщений в различных транспортных средствах, таких как in-process, межпроцессный, TCP и многоадресный. Вы можете соединять сокеты N-to-N с шаблоны, такие как разветвление, pub-sub, распределение задач и запрос-ответ. Это достаточно быстро, чтобы быть материалом для кластеризованных продуктов. это асинхронная модель ввода-вывода дает вам масштабируемые многоядерные приложения, построенных как асинхронные задачи обработки сообщений.

Преимущество использования 0MQ (или даже ванильных сокетов через сетевую библиотеку в ядре Node, минус все функции, предоставляемые сокетом 0MQ) заключается в отсутствии мастер-процесса. Его брокерская настройка лучше всего подходит для описываемого вами сценария. Если вы просто выталкиваете сообщения на различные узлы из одного центрального процесса, вы можете использовать PUB/SUB-сокет в 0mq (также поддерживает многоадресную передачу IP через PGM/EPGM). Кроме того, 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(вилка вышеупомянутого модуля, которая поддерживает фильтрацию PUBLISHER для PUBSUB):

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

Ответ 3

Спустя более 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);
            }
        );
    }
);

Im в настоящее время оценивает этот модуль для замены локального ipc (но может быть удаленным ipc в будущем) в качестве замены старого решения через stdin/stdout. Может быть, я расширю свой ответ, когда закончим, чтобы дать дополнительную информацию о том, как и как хорошо работает этот модуль.

Ответ 4

i начнется со встроенных функций, предоставляемых node.
вы можете использовать сигнализацию процесса, например:

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]), и сообщения будут получены событием "сообщение" для дочернего элемента.

Кроме того, вы можете использовать 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.io, signals и bean.

Ответ 5

взгляните на node -messenger

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

будет соответствовать большинству потребностей легко (паб/под... огонь и забыть.. отправить/запросить) с автоматическим поддерживаемым соединением

Ответ 6

мы работаем над многопроцессорным приложением node, которое требуется для обработки большого количества сообщений перекрестного процесса в реальном времени.

Сначала мы попробовали redis-pub-sub, который не соответствовал требованиям.

Затем попробовал tcp socket, который был лучше, но все же не самый лучший.

Итак, мы перешли на UDP-дейтаграмму, что намного быстрее.

Вот код репо, всего несколько строк кода. https://github.com/SGF-Games/node-udpcomm