У меня есть стек Amazon OpsWorks с HAProxy (balance = source) и несколько экземпляров node.js с socket.io. Кажется, HAProxy определяет максимальный предел сеанса для данного экземпляра на основе ограничений памяти этого экземпляра, и это нормально, но мое приложение часто может ожидать, что клиенты будут использовать две страницы, обе подключенные к сокету, в течение более 4 часов.
С максимальным лимитом сеансов в 40 или 180 я смогу иметь только 20/60 одновременных клиентов, пока один не отключится. Таким образом, с учетом сказанного, если лимит будет достигнут, другие клиенты будут помещены в очередь до тех пор, пока слот не станет свободным, что, учитывая характер сайта, вероятно, не будет в течение некоторого времени. Это означает, что у меня есть рабочий сайт только для серьезного меньшинства.
Как лучше всего обойти это? Я прочитал несколько сообщений, где у них будет бэкэнд от 4000 до 30 000 и максимальный лимит сеансов всего 30 на каждый сервер, но как они этого достигают? Есть ли настройка в HAProxy, или более вероятно, что они постоянно повторно подключают / отключают клиента через свое собственное приложение?
редактировать
Чтобы пролить свет на приложение - это само приложение PHP, которое использует сокеты для событий в реальном времени. Эти сокеты выполняются через socket.io
при этом сервер создается с использованием express
. это server.js
файл связывается с сервером Amazon ElastiCache Redis (который, насколько я понимаю, socket.io 1.0 обрабатывает всю эту внутреннюю часть).
На стороне клиента пользователь подключается к серверу сокетов и генерирует событие подключения, чтобы присоединиться к уникальной для него комнате. Затем пользователь загружает вторую страницу и снова генерирует событие подключения и присоединяется к той же уникальной комнате. Это затем позволяет им отправлять и получать различные события в течение сеанса - опять же, этот сеанс может длиться более 4 часов.
HAProxy направляет пользователя на тот же сервер на основе их IP-хэша (balance source
) - остальные параметры сохранены по умолчанию OpsWorks - см. файл конфигурации ниже.
Я думаю, что мне нужно знать, если Cur
сеансов достигает 40, и эти соединения являются долгоживущими (т.е. они не отключаются сразу), что произойдет с теми, кто находится в очереди? Ничего хорошего, если им придется ждать 4 часа, очевидно.
-
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);
});
});
Клиент
var socket = io.connect('http://haproxy_server_ip:80');
socket.on('connect', function() {
socket.emit('join', room id #);
});
Не видя никаких конфигураций, о которых вы говорите и о каких сайтах, я должен предположить, что они достигают количества сеансов в стандартном веб-приложении с http-server-close
. Так что в этом случае у вас будет много недолговечных соединений.
Лучший пример того, что вы делаете, - это веб-сокеты, которые представляют собой очень долгоживущие соединения. Для сети SE у нас есть maxconns
для нашего разрыва веб-сокета установлено значение 500000.
Что вы действительно хотите сделать, так это выяснить, сколько одновременных подключений вы хотите поддерживать в любой момент времени, и установить maxconn
ценность для этого. Конечно, вам нужно убедиться, что у вас достаточно ресурсов на балансировщике нагрузки для поддержки выбранного вами числа.
Я не думаю, что haproxy устанавливает эти ограничения. У меня есть подозрение, что может быть ограничение на количество разрешенных сеансов с одного и того же IP-адреса, поэтому, если вы тестируете его с одной машины, это, вероятно, будет вашей проблемой. Haproxy действительно может легко справиться с десятыми из тысяч соединений.