[英]Load Balance: Node.js - Socket.io - Redis
我有3台運行NodeJ的服務器,它們與Redis相互關聯(1個主節點,2個從節點)。
我遇到的問題是在一台服務器上運行系統可以正常工作,但是當我將其擴展到3個NodeJS服務器時,它開始丟失消息,系統變得不穩定。
我的負載均衡器不接受粘性會話。 因此,每次來自客戶端的請求到達時,它們都可以轉到其他服務器。
我將所有NodeJS服務器都指向Redis Master。
看起來socket.io正在每個服務器上存儲信息,並且沒有通過Redis進行分發。
我正在使用socket.io V9,我懷疑我沒有任何握手代碼,這可能是原因嗎?
我配置socket.io的代碼是:
var express = require('express');
var io = require('socket.io');
var redis = require('socket.io/node_modules/redis');
var RedisStore = require('socket.io/lib/stores/redis');
var pub = redis.createClient("a port", "an ip");
var sub = redis.createClient("a port", "an ip");
var client = redis.createClient("a port", "an ip");
var events = require('./modules/eventHandler');
exports.createServer = function createServer() {
var app = express();
var server = app.listen(80);
var socketIO = io.listen(server);
socketIO.configure(function () {
socketIO.set('store', new RedisStore({
redisPub: pub,
redisSub: sub,
redisClient: client
}));
socketIO.set('resource', '/chat/socket.io');
socketIO.set('log level', 0);
socketIO.set('transports', [, 'htmlfile', 'xhr-polling', 'jsonp-polling']);
});
// attach event handlers
events.attachHandlers(socketIO);
// return server instance
return server;
};
Redis僅從主機同步到從機。 它從不同步到從機。 因此,如果您要寫入所有3台計算機,則最終將在所有3台服務器之間同步的消息只有主服務器。 這就是為什么您看起來缺少消息的原因。
更多信息在這里 。
只讀奴隸
由於Redis 2.6從站支持默認情況下啟用的只讀模式。 此行為由redis.conf文件中的slave-read-only選項控制,並且可以在運行時使用CONFIG SET啟用和禁用。
只讀從站將拒絕所有寫命令,因此由於錯誤而無法寫入從站。 這並不意味着該功能被構想為將從屬實例公開到Internet,或更普遍地說是公開存在不信任客戶端的網絡,因為仍啟用了DEBUG或CONFIG之類的管理命令。 但是,可以通過使用rename-command指令禁用redis.conf中的命令來提高只讀實例的安全性。
您可能想知道為什么可以還原默認值並使從屬實例成為寫操作的目標。 原因是,如果從設備和主設備將重新同步,或者如果重新啟動了從設備,則該寫入將被丟棄 ,但是經常會有一些不重要的臨時數據可以存儲到從設備中。 例如,客戶端可以獲取有關從屬實例中主服務器可達性的信息,以協調故障轉移策略。
我到達了這篇文章:
在nodejs服務器和負載平衡器之間使用“代理”可能是一個好主意。 通過這種方法,XHR-Polling可以用於沒有“粘性”會話的負載均衡器中。
使用nodejs-http-proxy我可以自定義路由,例如。 通過在socket.io的“連接url”上添加參數。
有人嘗試過此解決方案嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.