我正在为一个现有的大型Rails应用程序添加WebSocket支持。我从一个简单的测试开始,只是为了确保它可以处理我们的生产负载-我们需要支持数千个活动连接,例如通知或聊天通道,每个活动连接对应于站点上的每个活动用户。
我已经部署了代码,它只是在页面加载时创建一个新的“PerfTestChannel”订阅:
App.cable.subscriptions.create('PerfTestChannel', ...)
它只为当前用户流:
class PerfTestChannel < ApplicationCable::Channel
def subscribed
stream_for current_user
end
end
在低流量下,它似乎工作得很好。它创建订阅并确认它:
然而,在较高的流量下,它会偶尔无法订阅该频道,并且spam subscribe
每秒无限期地重试两次:
我不知道为什么会失败,以及如何修复它。这很奇怪,因为如图所示,ping
消息仍在成功传输,因此电缆连接显然是打开的。它只是不会订阅PerfTestChannel
。
我们使用的是标准的Redis适配器设置。在测试中,我们有大约200个开放连接:
irb(main):016:0> Redis.new.pubsub("channels", "action_cable/*").count
=> 211
我们在生产日志中看到一些与Web套接字相关的错误:
第一个错误似乎不相关,因为(如上所述)很明显WebSocket升级是成功的,因为ping正在顺利进行。
第二个错误似乎是相关的。它是从源头的这一点来的:https://github.com/rails/rails/blob/main/actioncable/lib/action_cable/connection/base.rb#L94
不过,我不知道WebSocket是如何关闭的,因为ping的事情。所以,这也可能是一个红鲱鱼错误?
我们正在通过nginx-ingress使用负载平衡,它声称除了将超时提高到1小时之外,不需要任何特殊的websockets配置,我们已经这样做了,但无济于事。
1条答案
按热度按时间kjthegm61#
我想你可以试着做两个改变
1.增加Redis连接的数量。您可以通过在
config/cable.yml
文件中设置pool_size
选项来完成此操作,如下所示:1.检查您的nginx-ingress配置。检查
proxy_read_timeout
和proxy_send_timeout
值是否设置为足够高的值(例如1小时),并且proxy_http_version
值设置为1.1。