使用HAProxy负载平衡与Tornado应用程序的WebSocket连接?

我正在使用websocket处理程序的龙卷风应用程序。 我正在使用Supervisord运行应用程序的多个实例,但是在加载平衡websocket连接时遇到了问题。

我知道nginx不支持处理开箱即用的websockets,但是我按照这里的指示http://www.letseehere.com/reverse-proxy-web-sockets使用nginx tcp_proxy模块来反向代理websocket连接。 但是,这是不行的,因为模块不能路由websocket url(例如:ws:// localhost:80 / something)。 所以它不适用于我在我的Tornado应用中定义的URL路由。

从我对networking的研究中,似乎HAProxy是负载平衡我的websocket连接的方式。 然而,我很难find任何体面的指导来设置HAProxy负载平衡WebSocket连接,也能够处理WebSocket的URL路线。

我真的很感激一些关于如何实现这一目标的详细指导。 我也完全开放其他解决scheme。

在haproxy中实现WebSocket并不难,尽管我承认在这方面找到doc并不容易(希望这个回应会举一个例子)。 如果你使用haproxy 1.4(我想你是),那么它就像任何其他的HTTP请求一样工作,而不需要做任何事情,因为HTTP升级被haproxy识别。

如果要将WebSocket流量定向到与其余HTTP不同的场,那么您应该使用内容切换规则,简而言之:

 前端pub-srv
    绑定:80
     use_backend websocket if {hdr(Upgrade)-i WebSocket}
     default_backend http

 后端websocket
    超时服务器600s
    服务器节点1 1.1.1.1:8080检查
    服务器节点2 2.2.2.2:8080检查

 后端http
    超时服务器30s
    服务器www1 1.1.1.1:80检查
    服务器www2 2.2.2.2:80检查

如果您使用的是1.5-dev,甚至可以指定“超时隧道”,以使WS连接的超时时间比正常的HTTP连接超时,这样可以避免在客户端使用过长的超时。

你也可以结合Upgrade:WebSocket +一个特定的URL:

 前端pub-srv
    绑定:80
     acl is_websocket hdr(升级)-i WebSocket
     acl is_ws_url path / something1 / something2 / something3
     use_backend websocket if is_websocket is_ws_url
     default_backend http

最后,请不要使用我们有时看到的愚蠢的24小时闲置超时,现在等待客户24小时以上的会话绝对没有意义。 网络比80年代流动得多,连接也是非常短暂的。 你最终会得到许多FIN_WAIT套接字。 目前的互联网已经有十分钟的时间了。

希望这有助于!

WebSocket不能很好地遍历代理,因为握手之后他们没有遵循正常的HTTP行为。

尝试使用WebSocket(wss://)协议(安全的WS)。 这将使用Proxy CONNECT API来隐藏WebSocket协议。

我使用https://launchpad.net/txloadbalancer与Tornado websocket处理程序进行负载平衡。 这很简单,运作良好(我认为)。

http nginx(只有nginx v1.3 +)

upstream chatservice { #multi thread by tornado server 127.0.0.1:6661; server 127.0.0.1:6662; server 127.0.0.1:6663; server 127.0.0.1:6664; } map $http_upgrade $connection_upgrade { default upgrade; '' close; } 

虚拟主机

 server { listen 80; server_name chat.domain.com; root /home/duchat/www; index index.html index.htm; location / { try_files $uri $uri/ @backend; } location @backend { proxy_pass_header server; proxy_set_header X-Real-IP $remote_addr; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_set_header Host $host; proxy_pass http://chatservice; internal; }