前段时间 Ruby China 将 Web 段的 WebSocket 服务换成了 Rails 5 的 ActionCable: https://ruby-china.org/topics/28935
上线一段时间以后,我发现,每次 ActionCable 的服务启动完过一会儿就连不上了,浏览器表现为:
看起来像是 ActionCable 的服务连接太多,堵塞住了... 每次尝试重启 cable 的进程的瞬间又能连上...
然后,今天我终于找到问题原因了,Linux ulimit 限制的问题,之前服务器上面默认的 ulimit -Sn
只有 1024:
$ ulimit -Sn
1024
$ ulimit -Hn
4096
而由于 Ruby China 的访问量大,基本上一上线就会有超过这个数字的连接涌入,然后后续的就连不上了。
据我之前打印的 Cable 连接数来看,每次到 976 左右就连不上了,看起来是被 ulimit -Sn
这个值给限制了。
尝试修改了一下:
$ sudo vi /etc/security/limits.conf
增加两行,下面的 ruby
是我跑服务的用户名
ruby soft nofile 4096
ruby hard nofile 8192
登出重新登录
$ ulimit -Sn
4096
完整重启 ActionCable 以及 Nginx 进程,这下连接数上去了:
I, [2016-03-15T14:40:45.336305 #20278] INFO -- : [ActionCable] current connections: 1753
config.action_cable.allowed_request_origins = ['http://youhostname.com']
允许你的网站访问 ActionCable,不然连接会被拒绝,这里要注意要带上 http://
或 https://
;cookies.signed[:user_id]
的方式;# cable/config.ru
require ::File.expand_path('../../config/environment', __FILE__)
Rails.application.eager_load!
run ActionCable.server
新建一个 bin/cable:
bundle exec puma -p 28080 cable/config.ru
关于上面 4096,8192 数字的含义,你得跟进你的实际情况调整,我了解到的信息是可以理解能最大承受多少个连接,以应用场景好服务器配置、网络等。例如 Ruby China 平常都差不多 1700 多连接,我设定 4096 就可以了,设置太大,当一大堆连接过来的时候,会占满带宽,造成服务器无法访问。