我已经为我们的几个需要 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;
}
}
网络服务器配置
同样,这是其中一个站点的示例,其他站点具有类似的配置:
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 服务器正在侦听
location
的站点部分中创建一个。server
- 我需要将乘客对 websocket 位置的并发请求覆盖为无限制。
我的问题:
- 我是否还必须在负载均衡器的配置中启用乘客粘性会话?我猜这仅适用于网络服务器。
- websocket 服务器的
location
部分会是什么样子? - 我是否
location
还必须在负载均衡器上创建 websocket 部分? - 拥有粘性会话就足以使各种应用程序和服务器保持同步?
- 我在每台服务器上运行了各种应用程序,它们都应该收到相同的通知(套接字消息),所以它们都应该连接到同一个 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
有任何想法吗?