Load Balance: Node.js - Socket.io - Redis

I have 3 servers running NodeJs, and they are connected to each other using Redis (1 master, 2 subordinates).

The problem I am facing is that working on a system on a single server works fine, but when I scale it to 3 NodeJS servers, it starts to skip messages and the system becomes unstable.

My balancer does not accept sticky sessions. Therefore, every time requests from a client arrive at it, they can go to another server.

I point all NodeJS servers to Redis Master.

It seems that socket.io stores information on each server and is not distributed using redis.

I use socket.io V9, I suspect that I do not have handshake code, could this be the reason?

My code for setting socket.io is:

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; }; 
+4
source share
2 answers

Redis only syncs from master to slave. He never synchronizes with the slaves with the master. So, if you write to all 3 of your computers, then the only messages that will end on all three servers will be those that fall into the wizard. This is why it looks like you are missing messages.

More details here .

Only for reading

Since Redis 2.6 slaves support read-only mode, by default. This behavior is controlled by slave-read-only in the redis.conf file and can be enabled and disabled at run time using CONFIG SET.

Only slaves will reject all write commands, so it is not possible to write to the slave due to an error. This does not mean that the function is intended to put a subordinate instance on the Internet or, more generally, networks where unreliable clients exist, because administrative commands like DEBUG or CONFIG are still enabled. However, read-only security with examples can improve disabling commands in redis.conf using rename-command.

You may wonder why you can return by default and have subordinate instances that can be targeted for recording the operation. The reason is that although this record will be discarded if the slave and master are re-synchronized or if the slave is restarted, inaccurate data often appears that does not matter which can be stored in the slaves. For example, customers can retrieve master reachability information in a subordinate instance to coordinate a failover strategy.

+2
source

I came to this post:

It might be a good idea to have a β€œproxy” between the nodejs servers and the load balancer. With this approach, XHR polling can be used in load balancers without sticky sessions.

Load balancing using node.js using http-proxy

using nodejs-http-proxy I can have a custom routing route, e.g. adding a parameter to the "connect url" socket.io.

Has anyone tried this solution before?

0
source

Source: https://habr.com/ru/post/1485480/


All Articles