6

我有几个在 HAProxy 下运行身份验证的 socket.io 实例,我需要强制身份验证请求和套接字连接转到同一个实例。我已经根据这个对 SO question 的回答设置了 HAProxy,并进行了一些修改,如下所示:

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 是在身份验证调用和 websocket 连接中传递的查询字符串参数)和 source 作为平衡选项,但似乎 HAProxy 只允许这些选项用于 HTTP 连接,因此忽略它们用于实际的 websocket联系。结果是有时auth请求和socket连接最终在不同的服务器上,这对我们的应用程序来说是不可接受的。

有什么方法可以实现这种期望的行为?

4

5 回答 5

9

我以这种方式使用基于 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
于 2011-11-29T00:16:30.300 回答
3

stick_match为了平衡 TCP 连接,您可以使用orstick 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

此处提供完整文档。

于 2011-11-21T03:20:59.603 回答
0

您正在使用 HTTP,因此插入一个 cookie 以实现持久性 - 这绝对是最佳途径。除非它关闭,否则它将坚持到他们去的第一台服务器。

您还可以配置它是否应该在它关闭时重新调度它等。

于 2011-11-30T07:10:03.113 回答
0

对于 websocket 连接,使用roundrobin. 由于它的双向套接字(通过 TCP)默认保持粘性。对于其他传输使用source平衡算法是最好的选择。(您可以使用基于 cookie 的持久性,但 socket.io 不会将 JSESSIONID 等发送回代理服务器。如果您想要基于 cookie 的持久性,可以尝试sockjs 。)

例子:

#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
于 2011-11-16T10:29:26.793 回答
0

在我的情况下,我需要使用 对用户进行身份验证Authorization: Bearer ${ACCESS_TOKEN},对于这种身份验证,您可以使用stick_tables

以下配置将 balancer-host 端口80设置为跟踪并粘贴Authorization标头相同的连接:

frontend :80
   mode http
   bind :80
   default_backend http_servers

backend http_servers
    balance roundrobin
    stick-table type string len 600 size 1000m expire 5m
    stick on req.hdr(Authorization)
    server server81 192.168.1.1:81 weight 1 maxconn 512 check
    server server82 192.168.1.1:82 weight 1 maxconn 512 check
    server server83 192.168.1.2:83 weight 1 maxconn 512 check
于 2021-08-04T01:13:44.377 回答