gpt4 book ai didi

node.js - 具有粘性 session 的 Nodejs 集群

转载 作者:搜寻专家 更新时间:2023-10-31 22:53:28 24 4
gpt4 key购买 nike

const cluster = require('cluster');
const http = require('http');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
console.log(`Master ${process.pid} is running`);

// Fork workers.
for (let i = 0; i < numCPUs; i++) {
cluster.fork();
}

cluster.on('exit', (worker, code, signal) => {
console.log(`worker ${worker.process.pid} died`);
});
} else {
// Workers can share any TCP connection
// In this case it is an HTTP server



var sticky = require('sticky-session');
var express = require('express');
var app = express();

app.get('/', function (req, res) {
console.log('worker: ' + cluster.worker.id);
res.send('Hello World!');
});


var server = http.createServer(app);
sticky.listen(server,3000);

console.log(`Worker ${process.pid} started`);
}

我查阅了有关 nodejs 集群和粘性 session 的文档和另一个关于这个的堆栈溢出答案

  var cluster = require('cluster');
var http = require('http');
var sticky = require('sticky-session');
var express = require('express');
var app = express();

app.get('/', function (req, res) {
console.log('worker: ' + cluster.worker.id);
res.send('Hello World!');
});


var server = http.createServer(app);
sticky.listen(server,3000);

如果上面的代码片段在没有 fork 的情况下运行,它工作正常,但在其他情况下永远不会工作,如上面的集群示例所示,其中线程已启动但服务器从未初始化。

我读到有 sticky-cluster 的替代方案,有人可以就此主题给出适当的权威答案,这对寻找相同内容的人很有用,另一个主要问题是 app.locals 对象,它用于为一个应用程序实例存储变量,并且出现多个服务器实例会导致此中断,因为不同实例的值会有所不同,因此这种方法会导致一个大问题,并且应用程序会中断。回答时请不要复制粘贴一些代码,请提供详细信息详细回答该方法的优点和缺点。

我不是在寻找仅限于使用 sticky-sessions nodejs 模块的答案,我欢迎所有其他使用处理器所有内核但确保 session 连续性的方法。

如果它涉及 RedisStore 或 MongoDb 存储它没问题,我想知道的是关于具有 session 连续性集群的 nodejs 应用程序的标准方法

https://github.com/indutny/sticky-session

https://nodejs.org/api/cluster.html

https://stackoverflow.com/a/37769107/3127499

最佳答案

您的代码中存在一个小问题。“sticky-session”模块已经使用了 node.js“cluster”模块。你不需要“fork()”,因为 sticky- session 已经为你做了。让我们看看如何:

var cluster = require('cluster'); // Only required if you want the worker id
var sticky = require('sticky-session');

var server = require('http').createServer(function(req, res) {
res.end('worker: ' + cluster.worker.id);
});
sticky.listen(server, 3000);

调用 sticky.listen() 已经为您生成了 worker。请参阅下面的 listen() 实现

 function listen(server, port, options) {
if (!options)
options = {};

if (cluster.isMaster) {
var workerCount = options.workers || os.cpus().length;

var master = new Master(workerCount, options.env);
master.listen(port);
master.once('listening', function() {
server.emit('listening');
});
return false;
}
return true;
}

这一行 var master = new Master(workerCount, options.env) 负责产生 worker 。请参阅下面的 Master() 实现:

function Master(workerCount, env) {
net.Server.call(this, {
pauseOnConnect: true
}, this.balance);

this.env = env || {};

this.seed = (Math.random() * 0xffffffff) | 0;
this.workers = [];

debug('master seed=%d', this.seed);

this.once('listening', function() {
debug('master listening on %j', this.address());

for (var i = 0; i < workerCount; i++)
// spawning workers
this.spawnWorker();
});
}

所以实际上,当您调用 sticky.listen(server,port) 时,您实际上是在调用 cluster.fork()。因此您不应该再次显式调用 fork()。现在您的代码应该如下所示:

var cluster = require('cluster'); // Only required if you want the worker id
var sticky = require('sticky-session');

var server = require('http').createServer(function(req, res) {
res.end('worker: ' + cluster.worker.id);
});

//sticky.listen() will return false if Master
if (!sticky.listen(server, 3000)) {
// Master code
server.once('listening', function() {
console.log('server started on 3000 port');
});
} else {
// Worker code
}

需要记住的一件重要事情是,生成的 worker 将拥有自己的 EVENTLOOPmemory,因此彼此之间不会共享资源。您可以使用“REDIS”或其他 npm 模块(例如“memored”)在不同的工作人员之间共享资源。

希望这能解决您的两个问题。

关于node.js - 具有粘性 session 的 Nodejs 集群,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51301126/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com