Могу ли я иметь липкие сессии с HAProxy и socket.io с аутентификацией? - PullRequest
5 голосов
/ 16 ноября 2011

У меня есть несколько экземпляров socket.io с аутентификацией, работающей под HAProxy, и мне нужно заставить запрос аутентификации и соединение с сокетом идти к одному и тому же экземпляру.Я настроил HAProxy на основе этого ответа на вопрос SO с некоторыми изменениями следующим образом:

global
    maxconn     4096 # Total Max Connections. This is dependent on ulimit
    nbproc      2

defaults
    mode        http

frontend all 0.0.0.0:80
    timeout client 86400000
    default_backend www_backend
    acl is_websocket hdr(Upgrade) -i WebSocket
    acl is_websocket hdr_beg(Host) -i ws

    use_backend socket_backend if is_websocket

backend www_backend
    balance url_param sessionId
    option forwardfor # This sets X-Forwarded-For
    timeout server 30000
    timeout connect 4000
    server server1 localhost:8081 weight 1 maxconn 1024 check
    server server2 localhost:8082 weight 1 maxconn 1024 check
    server server3 localhost:8083 weight 1 maxconn 1024 check

backend socket_backend
    balance url_param sessionId
    option forwardfor # This sets X-Forwarded-For
    timeout queue 5000
    timeout server 86400000
    timeout connect 86400000
    server server1 localhost:8081 weight 1 maxconn 1024 check
    server server2 localhost:8082 weight 1 maxconn 1024 check
    server server3 localhost:8083 weight 1 maxconn 1024 check

Я пробовал url_param (где sessionId - параметр строки запроса, передаваемый в обоихвызов аутентификации и соединение веб-сокета) и источник в качестве параметров баланса, но кажется, что HAProxy разрешает эти параметры только для соединений HTTP и игнорирует их для фактического соединения веб-сокета.В результате иногда запрос на аутентификацию и подключение к сокету оказываются на разных серверах, что неприемлемо для нашего приложения.

Есть ли какой-нибудь способ получить такое желаемое поведение?

Ответы [ 4 ]

9 голосов
/ 29 ноября 2011

Я использую балансировку на основе cookie следующим образом:

backend socketio
    mode http
    cookie SIO insert
    server sock1 127.0.0.1:8001 cookie 001
    server sock2 127.0.0.1:8002 cookie 002
2 голосов
/ 21 ноября 2011

Для балансировки TCP-соединения вы можете добиться успеха с таблицей привязки, используя команды stick_match или stick on и явно устанавливая режим tcp.

Вот пример:

# forward SMTP users to the same server they just used for POP in the
# last 30 minutes
backend pop
    mode tcp
    balance roundrobin
    stick store-request src
    stick-table type ip size 200k expire 30m
    server s1 192.168.1.1:110
    server s2 192.168.1.1:110

backend smtp
    mode tcp
    balance roundrobin
    stick match src table pop
    server s1 192.168.1.1:25
    server s2 192.168.1.1:25

Полная документация доступна здесь .

0 голосов
/ 30 ноября 2011

Вы используете HTTP, поэтому вставьте cookie для сохранения - это, безусловно, лучший маршрут.Это приклеит его к первому серверу, на который они пошли, если он не выключен.

Вы также можете настроить, должен ли он повторно отправлять его, если он не работает и т. Д.

0 голосов
/ 16 ноября 2011

Для баланса веб-сокетов используйте roundrobin.Так как его двунаправленный сокет (через TCP) липкость поддерживается по умолчанию.Для других транспортов лучше использовать алгоритм балансировки source.(Вы можете использовать постоянство на основе файлов cookie, но socket.io не отправляет JSESSIONID или подобное обратно на прокси-сервер. Вы можете попробовать sockjs , если хотите использовать постоянство на основе файлов cookie.)

Пример:

#do the same for other transports. [Note in 0.6.x resource was mounted at path: /socket.io/[transport]
acl is_JSONPolling path_beg /socket.io/1/jsonp-polling
use_backend non_websocket if is_JSONPolling


backend non_websocket
  balance source
  #rest same as the one for websocket backend
...