35

私たちは、html5WebSocketを利用する必要があるRubyonRailsアプリに取り組んでいます。現在、いわば2つの別個の「サーバー」があります。nginx+passengerで実行されるメインアプリと、Pratik NaikのCrampフレームワーク( Thinで実行されている)を使用してWebSocket接続を処理する別個のサーバーです。

理想的には、デプロイの時期になると、Railsアプリがnginx +passengerで実行され、WebSocketサーバーがnginxの背後にプロキシされるため、WebSocketサーバーを別のポートで実行する必要はありません。

問題は、このセットアップでは、nginxがThinへの接続を早すぎて閉じているように見えることです。シンサーバーへの接続は正常に確立され、200応答コードですぐに閉じられます。私たちの推測では、nginxは、クライアントがWebSocketトラフィックの長時間実行接続を確立しようとしていることを認識していません。

確かに、私はnginx configに精通しているわけではないので、WebSocketサーバーのリバースプロキシとして機能するようにnginxを構成することも可能ですか?または、nginxが新しいWebSocketハンドシェイクのサポートを提供するのを待つ必要がありますか?アプリサーバーとWebSocketサーバーの両方がポート80でリッスンしていることが要件であるとすると、今のところnginxを使用せずにThinを別のサーバーで実行する必要があるのでしょうか。

アドバイスや提案を事前に感謝します。:)

-ジョン

4

7 に答える 7

26

現在、これにnginxを使用することはできません[もう真実ではありません]が、HAProxyを検討することをお勧めします。私はまさにこの目的のためにそれを使用しました。

秘訣は、ソケット接続が閉じられないように長いタイムアウトを設定することです。何かのようなもの:

timeout client  86400000 # In the frontend
timeout server  86400000 # In the backend

同じポートでレールとクランプアプリケーションなどを提供する場合は、ACLルールを使用してWebSocket接続を検出し、別のバックエンドを使用できます。したがって、haproxyフロントエンド構成は次のようになります。

frontend all 0.0.0.0:80
  timeout client    86400000
  default_backend   rails_backend
  acl websocket hdr(Upgrade)    -i WebSocket
  use_backend   cramp_backend   if websocket

完全を期すために、バックエンドは次のようになります。

backend cramp_backend
  timeout server  86400000
  server cramp1 localhost:8090 maxconn 200 check
于 2010-04-08T14:51:22.923 に答える
12

nginx_tcp_proxy_moduleモジュールを使用してみませんか?

このモジュールは、Nginxを使用した一般的なTCPプロキシ用に設計されています。WebSocketにも適していると思います。そして、開発ブランチにtcp_ssl_moduleを追加するだけです。

于 2010-09-14T09:03:05.463 に答える
11

nginx(> = 1.3.13)は、リバースプロキシWebSocketをサポートするようになりました。

# the upstream server doesn't need a prefix! 
# no need for wss:// or http:// because nginx will upgrade to http1.1 in the config below
upstream app_server {
    server localhost:3000;
}

server {
    # ...

    location / {
        proxy_pass http://app_server;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        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_redirect off;
    }
}
于 2013-02-20T10:00:38.083 に答える
7

箱から出して(つまり公式ソース)Nginxはアップストリーム(=バックエンド)へのHTTP 1.0接続のみを確立できます。つまり、キープアライブはありません。Nginxはアップストリームサーバーを選択し、サーバーへの接続を開き、プロキシ、キャッシュします(必要な場合) )接続を閉じます。それでおしまい。

これが、バックエンドへの永続的な接続を必要とするフレームワークがNginxを介して機能しない根本的な理由です(HTTP / 1.1 =キープアライブなし、WebSocketなし)。この欠点があるにもかかわらず、明らかな利点があります。Nginxは、いくつかのアップストリーム(負荷分散)から選択し、それらの一部が失敗した場合に、生きているものにフェイルオーバーできます。

編集:バージョン1.1.4以降、Nginxはバックエンドとキープアライブに対してHTTP1.1をサポートしています。「fastcgi」および「proxy」アップストリームがサポートされています。これがドキュメントです

于 2010-03-10T19:48:11.850 に答える
5

同じ問題について疑問に思っている人のために、nginxはHTTP1.1アップストリームを公式にサポートするようになりました。「keepalive」および「proxy_http_version1.1」については、nginxのドキュメントを参照してください。

于 2012-05-15T06:23:51.640 に答える
3

新しいHTTPプッシュモジュールを備えたNginxはどうですか:http://pushmodule.slact.net/。リバースプロキシで心配しなければならないかもしれない接続ジャグリング(いわば)を処理します。これは確かに、まだ完全にはミックスされていないWebsocketの実行可能な代替手段です。HTTPプッシュモジュールの開発者はまだ完全に安定したバージョンに取り組んでいますが、活発に開発されています。本番コードベースで使用されているバージョンがあります。著者の言葉を引用すると、「退屈な名前の便利なツール」です。

于 2010-03-10T20:08:01.617 に答える
2

私はnginxを使用して、ポーリング接続が長いコメットスタイルのサーバーにリバースプロキシします。これはうまく機能します。proxy_send_timeoutとproxy_read_timeoutを適切な値に設定してください。また、nginxのプロキシモジュールはまだhttp 1.1をサポートしていないと思うので、nginxがプロキシしているバックエンドサーバーがhttp1.0をサポートしていることを確認してください。

いくつかの回答の混乱を解消するために、キープアライブを使用すると、クライアントは接続を再利用して別のHTTPリクエストを送信できます。元の質問が尋ねていたイベントが発生するまで、長いポーリングや接続を開いたままにすることとは何の関係もありません。したがって、nginxのプロキシモジュールがキープアライブを持たないHTTP1.0のみをサポートすることは問題ではありません。

于 2010-05-26T11:51:55.803 に答える