我有一个socket应用程序运行使用NGNIX负载平衡和我的应用程序运行在6个核心和负载是分布在其中。当我执行pm2 list myapp时,它显示它运行在叉模式下,但跨越6个进程,这是由于nginx负载平衡的缘故。
│ 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上工作得很好,如果我在简单的1处理器中以叉子模式运行它,但是当我在NGNIX负载均衡器模式下运行它时,如果用户来自不同的IP,它就不会连接到两个用户。)或者我假设如果两者都有不同的过程。下面是我不想看到的情况,但现在已经发生了,
。
如何在进程-1到进程-6的所有进程之间共享我的全局变量及其值?
我已经在使用Redis了,您可以在下面看到https://socket.io/docs/using-multiple-nodes/,但它只能将发射事件传递给其他进程,我如何在myapp的所有进程之间共享队列变量以维护其持久状态和值?
理想情况下,我希望它像这样工作:
我只想让两个用户连接在一起,无论何时,无论他们来到这个共同的页面。如果第三次到来,它会一直处于等待状态(排队),直到第四次到来,然后第三次被弹出连接到第四次,依此类推。但是现在,我的变量队列在6个myapp进程中似乎是唯一的变量。
我使用Redis是这样的:
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中存储和检索变量队列的值/数组值的语法是什么。
发布于 2022-05-19 07:56:17
这个案子也是我的问题.我没有回答这个问题,但是..。可能是,您可以将变量临时用户切换到在负载平衡打开时具有复制功能的数据库。在这种情况下使用Redis是最好的之一。
https://stackoverflow.com/questions/58434139
复制相似问题