似乎所有节点唤醒器进程都在工作,就好像它正在执行同一应用程序的新副本一样。但是希望保留一些由节点集群中所有节点工作人员(子进程)共享的变量。有没有一种简单的方法可以做到这一点?
6 回答
所有工作进程确实是您的应用程序的新副本。每个 worker 都是使用 child_process.spawn 创建的全功能进程。所以不,他们不共享变量。这可能是最好的方式。如果您想在工作进程(通常是会话)之间共享信息,您应该考虑将这些信息存储在数据库中。
如果你准备好一直使用节点,你可以使用dnode 之类的东西让你的工作人员向主进程询问数据。
您可以尝试在主进程和子进程之间进行通信。例如:
脚本 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!');
});
脚本 test.child.js:
console.log('Child initializing..');
process.on('message', function(message) {
console.log('message from master: ', message);
});
process.send('Hello from Child!');
我为此使用了外部 memcached 或 redis 服务器。
我认为集群的整个想法是拥有可以在不同 cpu 上独立运行的实例。共享它们都可以访问和更改的内存(一个全局变量)会引入更多的复杂性(锁等)并使这些实例相互依赖。
外部数据库将是一个很好的解决方案,因为它可以解决所有数据访问问题,但它很可能会降低性能。
消息传递是一个更好的主意。您可以在集群中保存 var 的本地实例。当集群更新值时,向其余集群发送消息并更新值。这很棒,因为它是异步且非阻塞的,但您的值更新不会立即反映。
怎么样:将变量存储在数据库上,并且每次发生值更改时都会通知实例。他们可以将新值存储在本地变量中,并仅在需要时进行数据库调用
如果您希望以只读方式共享内容,请查看mmap-object。我将它用于大型内存查找表。
刚才在服务器上检查,一个 346M 的文件总共占用了 156M 的内存(mmap 仅在访问的页面中)并且 mmap-object 在 44 个进程之间共享它,每个进程的开销为 3.5M。
因为它是只读的,所以我不必担心进程间锁定和可能带来的混乱。
还没有人提到这一点,但这是Node Worker Threads的完美案例,它刚刚在最新版本的 Node v11.11.0 中退出了实验模式。