现在 Ruby China 已经跑在 Rails 5 上面了,并且已经用 ActionCable 代替了 message-bus 来实现实时的消息通知。
关于 Ruby China 升级 Rails 5 的改动,可以参考 https://github.com/ruby-china/ruby-china/pull/555 这个 PR,或许对你升级到 Rails 5 会有帮助。
由于很多 Gem 都还没有发布 Gem 版本,目前 Ruby China 还在直接应用它们 GitHub 的仓库地址。
ActionCable 实现改动看这个 Commit 就明白了:
https://github.com/ruby-china/ruby-china/commit/7193062fa3b8538af504ba470a23442dbdc01896
server {
server_name ruby-china.org;
location /cable {
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering on;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:7001;
gzip off;
}
}
ActionCable 的并发性能怎么样?有评测吗?现在是用 Node.JS 的 Socket.IO 在做实时消息,但感觉有些业务逻辑和 Rails 应用是重复的,如果 ActionCable 能很好地整合资源,并且有不错的性能,就尽快迁移到 Rails5 了。
@huacnlee @lgn21st 其实 ActionCable 的文档有误,所有支持 socket hijacking API 的 server 都是可以的,包括 Unicorn 还有 Passenger。
据最近一段时间 Ruby China 上面运作来看,需要将 ActionCable 独立部署在单独的 Puma 进程上面,避免堵塞。ActionCable 官方文档关于 Deployment 部分也是这么说的:
Action Cable is powered by a combination of websockets and threads. All of the connection management is handled internally by utilizing Ruby’s native thread support, which means you can use all your regular Rails models with no problems as long as you haven’t committed any thread-safety sins.
But this also means that Action Cable needs to run in its own server process. So you'll have one set of server processes for your normal web work, and another set of server processes for the Action Cable.
The Action Cable server does not need to be a multi-threaded application server. This is because Action Cable uses the Rack socket hijacking API to take over control of connections from the application server. Action Cable then manages connections internally, in a multithreaded manner, regardless of whether the application server is multi-threaded or not. So Action Cable works with all the popular application servers -- Unicorn, Puma and Passenger.
Action Cable does not work with WEBrick, because WEBrick does not support the Rack socket hijacking API.
https://github.com/rails/rails/tree/master/actioncable#deployment
另外,还有好多细节也会影响性能的,比如前端需要确保用户关闭页面或退出对应功能的时候,一定会 Unsubscribe 关掉连接,不然后端会保持很多 ActionCable Connection 无法释放。
connection to 'wss://ruby-china.org/cable' failed: WebSocket is closed before the connection is established. 我这显示
@huacnlee,打开浏览器端 firebug, 发现会定时出现 warning: WebSocket connection to 'wss://ruby-china.org/cable' failed: WebSocket is closed before the connection is established. 这是为什么呢?我根据 tutorial 里面的例子做了一个 server,也发现有类似的问题。
#42 楼 @huacnlee 我的问题解决了,参考https://github.com/rails/rails/tree/v5.0.0.beta3/actioncablerequest,应该是 origins 的问题
试试在 config/environments/production.rb 里修改配置:
# Action Cable endpoint configuration
config.action_cable.url = '/cable'
config.action_cable.allowed_request_origins = [ 'http://ruby-china.org' ]
[ActionCable] current connections: 976
一上线就将近 1K 的连接,检查了好多,还是没查到问题原因,依然过一会儿就连不上了。 本地调试过,看起来连接没有泄露,关掉浏览器以后都正常释放了的。
你好!你是否有这样的经历,我使用了 Rails5 的 ActionCable,服务器是 Nginx + Passenger,ActionCable 的 adapter 使用 redis,也进行了 namespace 设置,然后会出现服务器挂掉,如果把浏览器关了,也就是 unsubscribe channel 后,服务器有可以使用了。
我也遇到这个问题,只要浏览器连上 cable,网站就挂起半天打不开。只要把连上 cable 的页面关闭,网站马上就恢复正常了。服务器使用的是 Passenger+Nginx