Rails 关于 ActionCable 部署的细节经验分享

huacnlee · 2016年03月15日 · 最后由 huacnlee 回复于 2016年12月14日 · 6419 次阅读

前段时间 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

附带几个 ActionCable 部署的细节

  • 目前 ActionCable 服务无法自动重新载入新代码,所以开发环境你改了需要硬重启,同理生产环境也是一样,需要硬重启;
  • Puma, Thin, Unicorn, Passenger 都是可以跑的,没必要非得是 Thread 的,因为 ActionCable 用了 Rack socket hijacking API 来控制连接;
  • 官方文档里面建议要独立部署 ActionCable 的进程(之前我看到有,现在那段被去掉了),最新的文档里面说如果是 Puma 或 Thin 可以让 ActionCable 和网站主进程在一起;
  • 要注意修改 config/environments/production.rb 里面的:config.action_cable.allowed_request_origins = ['http://youhostname.com'] 允许你的网站访问 ActionCable,不然连接会被拒绝,这里要注意要带上 http://https://;
  • 在 WebSockets 没法访问 Rails 的 Session,不过 Cookie 是可以的,所以如果你需要在 Channel 里面读取用户信息的话,请用 cookies.signed[:user_id] 的方式;
  • WEBrick 没法跑,因为它不支持 Rack socket hijacking AP,不过这个不用担心,Rails 5 默认开发环境已经是 Puma 了。
  • robots.txt 屏蔽搜索引擎!

独立部署 ActionCable 的方式

# 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

参考阅读


Update 2015-05-05

关于上面 4096,8192 数字的含义,你得跟进你的实际情况调整,我了解到的信息是可以理解能最大承受多少个连接,以应用场景好服务器配置、网络等。例如 Ruby China 平常都差不多 1700 多连接,我设定 4096 就可以了,设置太大,当一大堆连接过来的时候,会占满带宽,造成服务器无法访问。

我想给楼主发红包。。。

👍👍👍

现在已经可以不用独立部署 ActionCable 了吧?

hesongGG [问题] 部署的时候碰到的一些问题 提及了此话题。 09月23日 20:34

@huacnlee 从 message bus 换到 action cable 是为了尝试新技术,还是确实前者优于后者?

#7 楼 @sqsy message_bus 是 long-polling 的方式,Action Cable 是 WebSockets 连接方式是不同的

message_bus 是周期性的,可能无法实时到达,例如 500ms 一次周期

需要 登录 后方可回复, 如果你还没有账号请 注册新账号