0

我已经为我们的几个需要 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部分会是什么样子?
  • 我是否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

有任何想法吗?

4

1 回答 1

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

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

于 2017-01-16T07:13:05.490 回答