proxy - 使用 HAProxy 对 Tornado 应用程序的 WebSocket 连接进行负载平衡?

标签 proxy nginx websocket tornado haproxy

我正在开发一个使用 websocket 处理程序的 Tornado 应用程序。我正在使用 Supervisord 运行该应用程序的多个实例,但在负载平衡 Websocket 连接时遇到问题。

我知道 nginx 不支持处理开箱即用的 websocket,但我按照此处的说明进行操作 http://www.letseehere.com/reverse-proxy-web-sockets使用 nginx tcp_proxy 模块来反向代理 websocket 连接。但是,这不起作用,因为模块无法路由 websocket url(例如:ws://localhost:80/something)。因此它不适用于我在 Tornado 应用程序中定义的 URL 路由。

根据我对网络的研究,HAProxy 似乎是对我的 websocket 连接进行负载平衡的方法。但是,我无法找到任何合适的指南来设置 HAProxy 以负载平衡 Websocket 连接,并且还能够处理 Websocket URL 路由。

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

最佳答案

在 haproxy 中实现 WebSocket 并不困难,尽管我承认目前还不容易找到这方面的文档(希望这个回复能成为一个例子)。如果您使用的是 haproxy 1.4(我想您是),那么它就像任何其他 HTTP 请求一样工作,无需执行任何操作,因为 HTTP 升级可以被 haproxy 识别。

如果您想将 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

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

您还可以组合升级: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

最后,请不要使用我们有时会看到的愚蠢的 24 小时空闲超时,这绝对不会 现在有必要等待客户 24 小时并建立 session 。网络还有更多 与 80 年代相比,移动设备和连接都非常短暂。你最终会得到许多 FIN_WAIT 套接字 不求返回。对于当前的互联网来说,10 分钟已经相当长了。

希望这有帮助!

关于proxy - 使用 HAProxy 对 Tornado 应用程序的 WebSocket 连接进行负载平衡?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10896175/

相关文章:

express - axios 请求获取连接 EHOSTUNREACH 错误。响应头得到默认源代码 'self'

python-2.7 - selenium firefox 中的 python 代理 headless 不工作

ruby-on-rails-3 - nginx 不在 Rails 3 中提供静态 Assets

用于后端通信的 RESTful HTTP 服务与直接 TCP 或 WebSockets

angular - 如何在 Angular 2 中设置反向代理

php - 如何更改 docker jwilder/nginx-proxy 上传限制?

angularjs - 如何在 Google 和 AngularJS 中将页面编入 "remove"

docker - 在kubernetes上通过Nginx Ingress中的服务公开容器中的基本路径

node.js - 长轮询的硬缺点?

azure - 从 Azure 订阅外部 Azure Web PubSub 服务