我可以通过身份验证与 HAProxy 和 socket.io 建立粘性会话吗?
我有几个在 HAProxy 下运行身份验证的 socket.io 实例,我需要强制身份验证请求和套接字连接转到同一个实例。我已经根据这个问题的答案设置了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 连接中忽略它们。结果是有时身份验证请求和套接字连接最终位于不同的服务器中,这对于我们的应用程序来说是不可接受的。
有什么方法可以实现这种理想的行为吗?
I have several instances of socket.io with authentication running under HAProxy and I need to force that the authentication request and the socket connection go to the same instance. I've set up HAProxy based on this answer to a SO question with some modifications as 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
I've tried url_param (where sessionId is a querystring parameter passed in both the authentication call and the websocket connection) and source as the balance options but it seems as if HAProxy only allows these options for HTTP connections and so ignores them for the actual websocket connection. The result is that sometimes the auth request and the socket connection end up in different servers, which is unacceptable for our application.
Is there some way to have this desired behavior?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我以这种方式使用基于 cookie 的平衡:
I use cookie based balancing in this way:
为了平衡 TCP 连接,您可以使用
stick_match
或stick on
命令并显式设置 tcp 模式,通过粘性表取得一些成功。以下是一个示例:
此处提供完整文档。
To balance TCP connection, you may have some success with a stickiness table using the
stick_match
orstick on
commands and explicitly setting tcp mode.Here is an example:
Full documentation available here.
对于 websocket 连接,使用
roundrobin
进行平衡。由于它是双向套接字(通过 TCP),默认情况下会保持粘性。对于其他传输,使用source
平衡算法是最好的选择。 (您可以使用基于 cookie 的持久性,但 socket.io 不会将 JSESSIONID 等发送回代理服务器。您可以尝试 sockjs(如果您想要基于 cookie 的持久性)。)示例:
For websocket connections balance using
roundrobin
. Since its a Bidirectional socket (over TCP) stickyness is maintained by default. For other transports usingsource
balancing algorithm is the best bet. (You can use cookie based persistence but socket.io doesn't send a JSESSIONID or the like back to the proxy server. You can try sockjs if you want cookie based persistence.)Example:
您使用的是 HTTP,因此请插入一个 cookie 以实现持久性 - 这绝对是最佳途径。这会将其粘贴到他们访问的第一台服务器上,除非该服务器出现故障。
您还可以配置是否在宕机等情况下重新调度它。
You're using HTTP so insert a cookie for persistence - that's definitely the best route. That'll stick it to the first server they went to unless it's down.
You can also configure whether it should redispatch it if it is down etc.
就我而言,我需要使用
Authorization: Bearer ${ACCESS_TOKEN}
对用户进行身份验证,对于这种身份验证,您可以使用 stick_tables。以下配置将平衡器主机端口
80
设置为跟踪并坚持Authorization
标头相同的连接:In my case I needed to authenticate the user using an
Authorization: Bearer ${ACCESS_TOKEN}
, for that kind of authentication you can use stick_tables.The following configuration sets the balancer-host port
80
to track and stick whose connections where theAuthorization
header is the same: