[英]How to share a global variable in node js multi cluster mode when socket io is running on NGNIX load balancer but on fork using pm2?
我有一個使用 NGNIX 負載平衡運行的套接字 io 應用程序,我的應用程序在 6 個內核上運行,負載分布在這些內核上。 當我執行pm2 list myapp
時,由於 nginx 負載平衡,它顯示它在 fork 模式下運行但跨越 6 個進程
│ 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 處理器中以 fork 模式運行它,但是當我在 NGNIX 負載均衡器模式下運行它時,如果他們來自不同的 IP,它不會連接 2 個用戶。 (或者我假設兩者都遇到了不同的過程。請參閱下面我不想要的場景,但現在正在發生這種情況,
如何在 myapp 的 process-1 到 process-6 的所有進程之間共享我的全局變量及其值?
我已經在使用 Redis,正如您在底部看到的https://socket.io/docs/using-multiple-nodes/但它只能將發出事件傳遞給其他進程,我如何共享我的隊列變量來維護它myapp的所有進程中的持久state和值?
理想情況下,我希望它像這樣工作:
我只希望 2 個用戶無論何時何地來到這個公共頁面都能連接在一起。 如果第 3 個出現,則一直等待 state(在隊列中),直到第 4 個出現,然后彈出第 3 個以連接到第 4 個,依此類推。 但現在我的變量 Queue 似乎是 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 中存儲和檢索變量隊列的值/數組值的語法是什么。
這種情況也是我的問題,.. 我還沒有回答這個問題,但是.. 可能你可以將變量臨時用戶切換到在負載平衡開啟時具有復制的數據庫.. 使用 Redis 是這種情況下最好的一種..
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.