Rails 4 + Websocket-rails + Passenger + Nginx + 负载均衡器
Posted
技术标签:
【中文标题】Rails 4 + Websocket-rails + Passenger + Nginx + 负载均衡器【英文标题】:Rails 4 + Websocket-rails + Passenger + Nginx + Load balancer 【发布时间】:2017-01-15 18:18:21 【问题描述】:我已经为我们的几个需要 websocket-rails 的网络应用程序添加了一些功能。在开发中一切正常,但我不确定如何在我们的生产环境中部署所有这些,因为它有点复杂。
生产设置:
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;
网络服务器配置
再次,这里是其中一个站点的示例,其他站点具有类似的配置:
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";
到目前为止我收集到的内容:
我需要启用passenger sticky sessions 我需要在网站的server
部分创建一个location
,Websocket 服务器正在侦听该部分。
我需要override the concurrent requests 的乘客才能将 websocket 位置设置为无限制。
我的问题:
我是否还必须在负载平衡器的配置中启用乘客粘性会话?我猜这仅适用于网络服务器。 websocket 服务器的location
部分是什么样的?
我是否还必须在负载平衡器上创建 websocket location
部分?
拥有粘性会话就足以使各种应用程序和服务器保持同步?
我在每台服务器上运行了各种应用程序,它们都应该接收相同的通知(套接字消息),因此它们都应该连接到同一个 websocket 服务器(我猜)。现在 websocket-rails 是他们 gemsets 的一部分,每个应用程序不会尝试生成自己的 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";
在客户端我连接到 url WebSocketRails('www.example.com/websocket');
并收到以下错误:
WebSocket connection to 'wss://www.example.com/websocket' failed: Error during WebSocket handshake: Unexpected response code: 404
有什么想法吗?
【问题讨论】:
【参考方案1】:我认为您不需要负载平衡器上的乘客粘性会话
blog 涵盖了 NGINX 的相关 WebSocket 配置。您需要负载均衡器上的 WebSocket 配置,如果您想将 Upgrade 和 Connection 标头传递给 rails 应用程序,还需要 Web 服务器上的配置。
【讨论】:
感谢您的输入,请查看我的更新以了解我到目前为止的内容。 我能看到的所有相关信息都在访问日志中:负载均衡器上的"GET /websocket HTTP/1.1" 404 731 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.112 Safari/537.36"
哦,我在应用服务器上也看到了同样的情况
您的 NGINX 配置似乎是正确的。我的猜测是乘客侧配置错误。乘客日志中是否有任何错误?
好吧,我找不到任何乘客日志,但查看应用服务器上 rails 应用程序的production.log
,我没有发现任何问题,甚至没有 404以上是关于Rails 4 + Websocket-rails + Passenger + Nginx + 负载均衡器的主要内容,如果未能解决你的问题,请参考以下文章