我可以通过authentication与HAProxy和socket.io进行粘性会话吗?

我有几个socket.io实例与HAProxy下运行身份validation,我需要强制authentication请求和套接字连接去同一个实例。 我已经根据这个答案build立了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是在身份validation调用和websocket连接传递的查询string参数)和来源作为平衡选项,但它似乎HAProxy只允许HTTP连接的这些选项,因此忽略它们的实际websocket连接。 结果是,有时authentication请求和套接字连接最终在不同的服务器上,这对于我们的应用是不可接受的。

有什么办法来达到这个理想的行为吗?

我以这种方式使用基于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 

为了平衡TCP连接,使用stick_matchstick 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 

完整的文档可在这里 。

对于websocket连接使用roundrobin平衡。 由于其双向套接字(通过TCP)粘性保持默认。 对于使用source平衡algorithm的其他传输是最好的select。 (您可以使用基于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 

你使用HTTP,所以插入一个cookie来保存 – 这绝对是最好的路线。 这将坚持到他们去的第一台服务器,除非它停机。

你也可以configuration它是否应该重新调度,如果它是closures等