2011-11-16 126 views
5

我有几个socket.io实例在HAProxy下运行身份验证,我需要强制认证请求和套接字连接去同一个实例。我已经设置了HAProxy的基础上this answer to a SO question有一些修改为这样:我可以通过身份验证与HAProxy和socket.io进行粘性会话吗?

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连接传递一个查询字符串参数)和源作为平衡选项,但似乎HAProxy只允许HTTP连接的这些选项,因此忽略它们以用于实际的websocket连接。其结果是,有时认证请求和套接字连接最终会在不同的服务器中出现,这对我们的应用程序来说是不可接受的。

有没有某种方法来获得这种理想的行为?

+0

你有没有想过最好的方法来做到这一点?我期待着做同样的事情。谢谢。 –

+0

我结束了使用IP哈希平衡。所有来自同一个IP的请求都会转到同一台服务器 – Diego

+0

O ok,但这是否意味着从服务器A上的用户广播的websocket不会到达服务器B上的任何用户? –

回答

0

对于使用roundrobin的websocket连接余额。由于它的双向套接字(通过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 
+0

问题是身份验证请求和websocket连接可能以不同的服务器结束。有没有办法让他们总是去同一台服务器?你知道是否有其他负载平衡器提供这个? – Diego

+0

只要您的授权存储与应用程序分开,无论哪台服务器都受到影响。希望你没有使用内存作为你的auth会话存储。使用类似Redis的内容来存储授权密钥。看看我的答案在这里处理auth:http://stackoverflow.com/questions/4753957/socket-io-authentication/4754806#4754806 –

2

要平衡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 

可用here完整文档。

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 
+0

对于cookie方法,有没有办法设置cookie超时期限? – Alessandro

0

您使用HTTP所以插入一个cookie的持久性 - 这是绝对的最佳途径。这将坚持到他们去的第一台服务器,除非它停机。

您还可以配置它是否应该重新发送它,如果它是关闭等

相关问题