Javascript 当socket io在NGNIX负载平衡器上运行,但在使用pm2的fork上运行时,如何在node js多集群模式下共享全局变量?
我有一个socket io应用程序正在使用NGNIX负载平衡运行,我的应用程序运行在6个内核上,负载分布在这些内核之间。当我执行pm2 list myapp时,它显示它在fork模式下运行,但由于nginx负载平衡,它跨越了6个进程Javascript 当socket io在NGNIX负载平衡器上运行,但在使用pm2的fork上运行时,如何在node js多集群模式下共享全局变量?,javascript,node.js,nginx,socket.io,pm2,Javascript,Node.js,Nginx,Socket.io,Pm2,我有一个socket io应用程序正在使用NGNIX负载平衡运行,我的应用程序运行在6个内核上,负载分布在这些内核之间。当我执行pm2 list myapp时,它显示它在fork模式下运行,但由于nginx负载平衡,它跨越了6个进程 │ myapp-1 │ 21 │ fork │ │ myapp-2 │ 45 │ fork │ │ myapp-3 │ 32 │ fork │ │ myapp-4 │ 11 │ fork │
│ myapp-1 │ 21 │ fork │
│ myapp-2 │ 45 │ fork │
│ myapp-3 │ 32 │ fork │
│ myapp-4 │ 11 │ fork │
│ myapp-5 │ 911 │ fork │
│ myapp-6 │ 101 │ fork │
下面是我的ngnix文件的外观示例
# Nodes for load balancing myapp
upstream myapp_nodes{
ip_hash;
server 1.2.3.4:1001;
server 1.2.3.4:1002;
server 1.2.3.4:1003;
server 1.2.3.4:1004;
server 1.2.3.4:1005;
server 1.2.3.4:1006;
}
在我的myapp.js中,我有一个全局变量,称为Queue
,当用户出现在页面上并等待与另一个人连接时,该变量存储用户。当另一个人来时,老人从队列中弹出,他们共享一个共同的ID一起聊天。我正在使用第一个人的socket.id作为房间
示例代码
var Queue = []; //global array of people waiting to chat
socket.on("newUserJoinedFromClient", function (Username) {
//check if someone is already waiting then pop it and return the pop SID as room
if (Queue.length > 0) {
var partner = Queue.pop();
//remove special char from SID
var room = partner.id.replace(/[^a-zA-Z0-9]/g, "");
//return and tell the client its room
socket.emit('sendRoomToClient', {
room: room,
users: numUsers
}); //this person room will be same as the waiting partner room
}
// if nobody is in queue, queue is empty
else {
//add this user socket id to queue
Queue.push(socket);
//remove special char from SID
var room = socket.id.replace(/[^a-zA-Z0-9]/g, "");
//return and tell the client its room
socket.emit('sendRoomToClient', {
room: room,
users: numUsers
}); // Because we are calling socket itself id as his room, and he will wait
}
});
在单核myapp.js上,如果我在simple 1处理器中以fork模式运行它,逻辑似乎工作得非常完美,但是当我在NGNIX负载平衡器模式下运行它时,如果两个用户来自不同的IP,它就无法连接到他们。(或者我假设两者都在不同的过程中发生。请参阅下面的场景,我不想看到,但现在正在发生这种情况
var app = express();
if (process.env.ENV == "development") {
var server = require("http").createServer(app);
} else {
// Setting up a HTTPS Server
var server = require("https").createServer(,
app // i have removed configs for https.
);
}
var io = require('socket.io');
var redis = require("socket.io-redis");
io.adapter(redis({
host: "localhost",
port: 6379
}));
server.listen(port, function () {
console.log("Server listening at port %d", port);
});
io.attach(server);
然后
io.sockets
.on('connection', socketioJwt.authorize({
hash: jwt,
timeout: 15000 // 15 seconds to send the authentication message
})).on('authenticated', function (socket) {
//all socket io events go here
});
我不确定在Redis中存储和检索变量队列的值/数组值的语法是什么。这是因为每个进程都运行自己的
队列
。您需要使用Redis
或其他东西,以便所有进程共享相同的队列
。您提到您已经在使用Redis
,但我在你的代码中看不到。不过,你的队列应该在redis
中读/写。想想看redis
是你的全局数据库。@Raul是的,我在使用redis,我已经用我正在使用的redis代码更新了我的问题。它只是像在这个redislin上建议的那样围绕着套接字io适配器socket io文档的k。所以我不是100%确定redis我在这个例子中使用redis。你能告诉我在redis中存储和检索全局变量Queue
的语法,而不是像我现在这样在我的普通myapp.js文件中作为全局变量。我如何在redis中存储和获取变量数据?如果我没有错,你会怎么做当前正在使用redis的只是socket.io通信部分。但是,当有人加入您的页面时,您可以查看队列
对象,该对象在脚本中是全局的,但对每个实例都是局部的。因此,我想您所要做的就是读取和写入一个中心redis实例。看看示例,可能会帮助您开始。@Raul i am alr我已经在代码中使用socket.io-redis模块了,所以我需要这个require('redis'))
模块?请查看上面的代码,并让我知道如何在socket io存储中存储我的队列
变量。我正在尝试按照此处的指南操作,但它不起作用。如果您能在下面给我代码示例,用redis store and store配置我的socket io,并获取我的队列变量
,我会给您最好的答案。我很抱歉我不是Redis的专家