使用HAProxy将负载平衡WebSocket连接到Tornado应用程序?
我正在开发一个使用websocket处理程序的Tornado应用程序。我正在使用Supervisord运行多个应用程序实例,但在负载平衡websocket连接时遇到问题 我知道nginx不支持即时处理websocket,但我按照这里的说明使用nginx tcp_代理模块来反转代理websocket连接。但是,这不起作用,因为模块无法路由websocket URL(例如:ws://localhost:80/something)。因此,它无法与我在Tornado应用程序中定义的URL路由一起工作 从我对web的研究来看,HAProxy似乎是平衡websocket连接负载的方法。然而,我很难找到任何合适的指南来设置HAProxy以实现websocket连接的负载平衡,并能够处理websocket URL路由使用HAProxy将负载平衡WebSocket连接到Tornado应用程序?,proxy,nginx,websocket,tornado,haproxy,Proxy,Nginx,Websocket,Tornado,Haproxy,我正在开发一个使用websocket处理程序的Tornado应用程序。我正在使用Supervisord运行多个应用程序实例,但在负载平衡websocket连接时遇到问题 我知道nginx不支持即时处理websocket,但我按照这里的说明使用nginx tcp_代理模块来反转代理websocket连接。但是,这不起作用,因为模块无法路由websocket URL(例如:ws://localhost:80/something)。因此,它无法与我在Tornado应用程序中定义的URL路由一起工作 从
我真的很感激一些关于如何进行这项工作的详细说明。我也对其他解决方案持完全开放态度。WebSocket不能很好地遍历代理,因为在握手之后,它们没有遵循正常的HTTP行为
尝试使用WebSocket(wss://)协议(安全WS)。这将使用代理连接API,该API将隐藏WebSocket协议。在haproxy中实现WebSocket并不困难,尽管我承认在这方面还不容易找到文档(希望此响应将提供一个示例)。如果您使用的是haproxy 1.4(我想您是这样),那么它的工作原理与任何其他HTTP请求一样,无需执行任何操作,因为haproxy可以识别HTTP升级 如果要将WebSocket流量定向到与HTTP其余部分不同的服务器场,则应使用内容切换规则,简而言之: frontend pub-srv bind :80 use_backend websocket if { hdr(Upgrade) -i WebSocket } default_backend http backend websocket timeout server 600s server node1 1.1.1.1:8080 check server node2 2.2.2.2:8080 check backend http timeout server 30s server www1 1.1.1.1:80 check server www2 2.2.2.2:80 check 前端酒吧 绑定:80 如果{hdr(升级)-i websocket} 默认后端http 后端websocket 超时服务器600s 服务器节点1.1.1.1:8080检查 服务器节点2.2.2.2:8080检查 后端http 服务器超时30s 服务器www1 1.1.1.1:80检查 服务器www2 2.2.2.2:80检查 如果您使用的是1.5-dev,您甚至可以指定“timeout tunnel”,使WS-connections的超时时间大于普通HTTP连接的超时时间,从而避免在客户端使用过长的超时时间 您还可以将Upgrade:WebSocket与特定URL结合使用: frontend pub-srv bind :80 acl is_websocket hdr(Upgrade) -i WebSocket acl is_ws_url path /something1 /something2 /something3 use_backend websocket if is_websocket is_ws_url default_backend http 前端酒吧 绑定:80 acl是\u websocket hdr(升级)-i websocket acl是\u ws\u url路径/something1/something2/something3 如果是,则使用后端websocket 默认后端http 最后,请不要使用我们有时会看到的愚蠢的24小时空闲超时,这绝对是不可能的 立即使用已建立的会话等待客户机24小时。网络要多得多 与80年代相比,移动和连接都是非常短暂的。你最终会有很多个FIN_等插座 白白的。10分钟对于目前的互联网来说已经相当长了 希望这有帮助 我曾经使用Tornado websocket处理程序进行负载平衡。它很简单,而且运行良好(我认为)。HTTPNginx(仅限nginx v1.3+) 虚拟主机
那么你是说如果我使用WSS://那么url处理就可以实现?我不同意,事实上恰恰相反,握手是100%符合HTTP的,并且是为此而设计的,但是它使用了HTTP的升级功能,而在过去,许多代理并不关心实现这一功能。如果您的代理不支持升级机制,请向您的供应商提交错误报告,这对于修复web非常重要!是的,Amir,WSS绕过了代理需要从升级中实现的逻辑。它使It在不进行任何干预的情况下处理背对背的连接。感谢您提供的详细且信息丰富的回复。我今天会试试,然后回来汇报。我知道您表示不喜欢高空闲超时,您的观点对大多数应用程序都有意义。我实际上使用WebSocket在嵌入式设备和服务器之间创建通信。该设备实际上将永远处于开启状态(理论上)。那么有没有一种方法可以完全不超时呢?@AmirR。我也希望实现一个类似的设置,希望听到你的结果,采用上述答案。你可以禁用超时,如果你想(并将得到警告)。但这始终是一个设计错误,因为您假设设备永远不会出现故障/崩溃/重新启动/断开连接,这是100%错误的。请记住,存在超时是为了保护一个组件不受另一个组件意外故障的影响。当你的设备出现故障时,你不想重新启动haproxy来摆脱fantom连接,这是没有意义的。
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;
}