Rails 4+Websocket Rails+Passenger+Nginx+负载均衡器



我为我们的几个需要websocket rails的web应用程序添加了一些功能。在开发中一切都很好,但我不确定如何在我们的生产环境中部署所有这些,因为它有点复杂。

生产设置:

  • 1台服务器用作负载均衡器(Nginx)
  • 2台服务器用作web服务器,其中我们的rails应用程序使用Nginx和Passenger运行(两台服务器相同)
  • 应用服务器使用的其他几个服务器,但我认为它们与这个问题无关
  • 所有站点都在HTTPS上运行

负载均衡器配置

以下是其中一个站点的示例,其他站点具有类似的配置:

upstream example {
ip_hash;
server xx.xx.xx.xx:443;
server xx.xx.xx.xx:443;
}
server {
listen   80;
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/example.chained.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
server_name example.com;
rewrite ^(.*) https://www.example.com$1 permanent;
}
server {
listen   80;
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/example.chained.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
server_name www.example.com;
if ($ssl_protocol = "") {
rewrite     ^   https://$server_name$request_uri? permanent;
}
client_max_body_size 2000M;
location /css { root /home/myuser/maintenance; }
location /js { root /home/myuser/maintenance; }
location /img { root /home/myuser/maintenance; }
location /fonts { root /home/myuser/maintenance; }
error_page 502 503 @maintenance;
location @maintenance {
root /home/myuser;
if ($uri !~ ^/maintenance/) {
rewrite ^(.*)$ /maintenance/example.html break;
}
}
location / {
proxy_pass https://example;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

Web服务器配置

同样,这里有一个站点的例子,其他站点有类似的配置:

server {
server_name example.com;
rewrite ^(.*) https://www.example.com$1 permanent;
}
server {
listen   80;
listen 443 ssl;
ssl on;
ssl_certificate /etc/nginx/ssl/example.chained.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
root /var/www/example/public;
server_name www.example.com;
if ($ssl_protocol = "") {
rewrite     ^   https://$server_name$request_uri? permanent;
}
client_max_body_size 2000M;
passenger_enabled on;
rails_env production;
passenger_env_var SECRET_KEY_BASE "SOME_SECRET";
}

到目前为止我收集到的信息:

  • 我需要启用乘客粘性会话
  • 我需要在websocket服务器正在侦听的站点的server部分创建一个location
  • 我需要覆盖乘客对websocket位置的并发请求,使其不受限制

我的问题:

  • 我是否也必须在负载平衡器的配置中启用乘客粘性会话?我猜这只适用于网络服务器
  • websocket服务器的location部分会是什么样子
  • 我是否也必须在负载均衡器上创建websocketlocation部分
  • 有粘性会话就足以让各种应用程序和服务器保持同步吗
  • 我在每台服务器上都运行着各种应用程序,它们都应该收到相同的通知(套接字消息),所以它们都应该连接到同一个websocket服务器(我猜)。既然websocketrails是它们的gemset的一部分,难道每个应用程序都不会尝试生成自己的websocket服务器吗?如果是这样的话,我该如何防止这种情况发生,并使它们只产生一个,以防还没有运行

正如你所看到的,我对websocket rails在生产中如何与乘客和nginx一起工作感到非常困惑,所以即使你不知道所有的答案,也非常感谢你的任何意见!

更新

我在负载均衡器上尝试了以下操作:

upstream websocket {
server xx.xx.xx.xx:443;
server xx.xx.xx.xx:443;
}
location /websocket {
proxy_pass https://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#also tried with this:
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
}

以及在应用程序服务器上:

location /websocket {
proxy_pass https://www.example.com/websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#also tried with this:
#proxy_set_header Upgrade $http_upgrade;
#proxy_set_header Connection "upgrade";
}

在客户端,我连接到urlWebSocketRails('www.example.com/websocket');,并得到以下错误:

WebSocket connection to 'wss://www.example.com/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404

有什么想法吗?

  1. 我认为您不需要在负载均衡器上进行乘客粘性会话

  2. 本博客介绍了NGINX的相关WebSocket配置。如果要将Upgrade和Connection标头传递到rails应用程序,则需要在负载平衡器上以及在web服务器上进行WebSocket配置。

相关内容

  • 没有找到相关文章

最新更新