J'ai une pile Amazon OpsWorks exécutant HAProxy (balance = source) et plusieurs instances node.js exécutant socket.io. Il semble que HAProxy détermine la limite de session maximale pour une instance donnée en fonction des limites de mémoire de cette instance, ce qui est bien, mais mon application peut souvent s'attendre à ce que les clients utilisent deux pages, toutes deux connectées à un socket, pendant plus de 4 heures.
Avec la limite maximale de sessions à 40 ou 180, je ne pourrais avoir que 20/60 clients simultanés jusqu'à ce que l'un d'eux se déconnecte. Cela dit, si la limite est atteinte, les autres clients seront placés dans une file d'attente jusqu'à ce qu'un créneau se libère, ce qui, étant donné la nature du site, risque de ne pas être le cas avant un certain temps. Cela signifie que je n'ai un site fonctionnel que pour une minorité sérieuse.
Quelle est la meilleure façon de contourner ce problème ? J'ai lu plusieurs messages indiquant qu'ils auront un backend de 4 000 à 30 000 et une limite de session maximale de seulement 30 par serveur, mais comment y parviennent-ils ? Y a-t-il un paramètre dans HAProxy, ou est-il plus probable qu'ils reconnectent/déconnectent continuellement le client via leur application ?
Modifier
Pour en savoir plus sur l'application, il s'agit d'une application PHP qui utilise des sockets pour les événements en temps réel. Ces sockets sont utilisés à travers socket.io
avec ce serveur étant généré en utilisant express
. Ce site server.js
communique avec un serveur Amazon ElastiCache Redis (qui, d'après ce que j'ai compris, gère tout ce backend en socket.io 1.0).
Du côté client, les utilisateurs se connectent au serveur de socket et émettent un événement de connexion afin de rejoindre une salle qui leur est propre. L'utilisateur charge ensuite une deuxième page et émet à nouveau un événement de connexion pour rejoindre cette même salle unique. Cela lui permet ensuite d'émettre et de recevoir divers événements au cours de sa session, qui peut durer jusqu'à 4 heures.
HAProxy achemine l'utilisateur vers le même serveur en fonction de son hachage IP ( balance source
) - le reste des options est conservé par défaut dans OpsWorks - voir le fichier de configuration ci-dessous.
Je suppose que ce que j'ai besoin de savoir c'est si Cur
atteint 40, et que ces connexions sont de longue durée (c'est-à-dire qu'elles ne sont pas déconnectées rapidement), qu'adviendra-t-il de celles qui sont dans la file d'attente ? Il n'est pas bon qu'elles restent en attente pendant 4 heures, évidemment.
--
HAProxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
#log loghost local0 info
maxconn 80000
#debug
#quiet
user haproxy
group haproxy
stats socket /tmp/haproxy.sock
defaults
log global
mode http
option httplog
option dontlognull
retries 3
option redispatch
maxconn 80000
timeout client 60s # Client and server timeout must match the longest
timeout server 60s # time we may wait for a response from the server.
timeout queue 120s # Don't queue requests too long if saturated.
timeout connect 10s # There's no reason to change this one.
timeout http-request 30s # A complete request may never take that long.
option httpclose # disable keepalive (HAProxy does not yet support the HTTP keep-alive mode)
option abortonclose # enable early dropping of aborted requests from pending queue
option httpchk # enable HTTP protocol to check on servers health
stats auth strexm:OYk8834nkPOOaKstq48b
stats uri /haproxy?stats
# Set up application listeners here.
listen application 0.0.0.0:80
# configure a fake backend as long as there are no real ones
# this way HAProxy will not fail on a config check
balance source
server localhost 127.0.0.1:8080 weight 1 maxconn 5 check
Server.js
var express = require('express');
var app = express();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('socket.io-redis');
io.adapter(redis({ host: ###, port: 6379 }));
server.listen(80); // opsworks node.js server requires port 80
app.get('/', function (req, res) {
res.sendfile('./index.html');
});
io.sockets.on('connection', function (socket) {
socket.on('join', function(room) {
socket.join(room);
});
socket.on('alert', function (room) {
socket.in(room).emit('alert_dashboard');
});
socket.on('event', function(data) {
socket.in(data.room).emit('event_dashboard', data);
});
});
Client
var socket = io.connect('http://haproxy_server_ip:80');
socket.on('connect', function() {
socket.emit('join', room id #);
});