我有几个socket.io实例,在HAProxy下运行身份验证,我需要强制认证请求和套接字连接转到同一个实例。我已根据this answer to a 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请求和套接字连接有时会在不同的服务器中结束,这对我们的应用程序来说是不可接受的。
有没有办法实现这种理想的行为?
答案 0 :(得分: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
答案 1 :(得分:2)
要平衡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
完整文档here。
答案 2 :(得分:0)
使用roundrobin
进行websocket连接平衡。由于默认情况下保持双向套接字(通过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
答案 3 :(得分:0)
您正在使用HTTP,因此请插入Cookie以保持持久性 - 这绝对是最佳路线。这将坚持到他们去的第一台服务器,除非它失败了。
您还可以配置是否应该在关闭等时重新发送它。
答案 4 :(得分:0)
就我而言,我需要使用 Authorization: Bearer ${ACCESS_TOKEN}
对用户进行身份验证,对于这种身份验证,您可以使用 stick_tables。
以下配置将平衡器主机端口 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