Кажется, что все woker-процессы node работают так, как будто он выполняет новую копию того же приложения. Но хотелось бы сохранить некоторые переменные, которые совместно используются всеми рабочими node (дочерние процессы) в кластере node. Есть ли простой способ сделать это?
Как сохранить переменные, которые делят все процессы node в кластере node?
Ответ 1
Все рабочие процессы действительно являются новыми копиями вашего приложения. Каждый рабочий является полнофункциональным процессом, созданным с помощью child_process.spawn. Нет, они не разделяют переменные. И это, вероятно, лучше всего. Если вы хотите обмениваться информацией между рабочими процессами (обычно сеансами), вы должны посмотреть на сохранение этих данных в базе данных.
Если вы готовы пройти node полностью, вы можете использовать что-то вроде dnode, чтобы ваши рабочие спросили мастер-процесс о данных.
Ответ 2
Вы можете попытаться установить связь между основным процессом и дочерними процессами. Например:
script test.master.js:
var cluster = require('cluster');
var childScript = __dirname + '/test.child.js';
cluster.setupMaster({ exec: childScript });
proc = cluster.fork();
proc.on('message', function(message) {
console.log('message from child: ', message);
proc.send('Hello from master!');
});
script test.child.js:
console.log('Child initializing..');
process.on('message', function(message) {
console.log('message from master: ', message);
});
process.send('Hello from Child!');
Ответ 3
Я использовал для этого внешний сервер memcached или redis.
Ответ 4
Я думаю, что вся идея кластера имеет экземпляры, которые могут работать независимо друг от друга на разных процессорах. Общий доступ к памяти (глобальная переменная), к которой они оба могут получить доступ и изменения, вводит большую сложность (блокировки и т.д.) И заставляет эти экземпляры зависеть друг от друга.
Внешняя база данных будет хорошим решением для этого, поскольку она заботится обо всех проблемах доступа к данным, но, скорее всего, снижает производительность.
Сообщения - лучшая идея. Вы можете хранить локальные экземпляры var в ваших кластерах. Когда кластер обновляет значение, отправьте сообщение остальным и обновите значение. Это здорово, потому что это асинхронно и неблокируется, но снова ваше обновление значения сразу не отразится.
Как насчет этого: храните vars на db и каждый раз, когда изменение значения уведомляет экземпляры. Они могут сохранять новые значения в локальных vars и делать вызовы db только тогда, когда это необходимо
Ответ 5
Если вы хотите делиться вещами только для чтения, просмотрите mmap-object. Я использую его для больших таблиц поиска в памяти.
Проверяя прямо сейчас на сервере, файл 346M занимает в общей сложности 156 Мбайт памяти (только для mmap-страниц в том, что доступно), а mmap-объект использует его среди 44 процессов для служебных издержек на каждый процесс 3.5M.
Поскольку это только для чтения, мне не нужно беспокоиться о блокировке между процессами и беспорядочности, которые могут принести.