nginxは、バックエンドWebsocketサーバーのリバースプロキシとして使用できますか?
-
19-09-2019 - |
質問
HTML5 WebSocketsを利用する必要があるRuby on Railsアプリに取り組んでいます。現時点では、いわば2つの独立した「サーバー」があります。NGINX+乗客で実行されているメインアプリと、Pratik Naik'sを使用して別のサーバーがあります。 けいれん フレームワーク(実行中です 薄い)WebSocket接続を処理します。
理想的には、展開の時が来たら、nginx+乗客でRailsアプリを実行し、WebSocketサーバーはNGINXの背後にプロキシ化されるため、WebSocketサーバーを別のポートで実行する必要はありません。
問題は、このセットアップでは、Nginxが接続を閉じて薄すぎて早すぎるようです。接続はThin Serverに正常に確立され、200回の応答コードですぐに閉じられました。私たちの推測では、Nginxは、クライアントがWebsocketトラフィックの長期にわたる接続を確立しようとしていることを認識していないということです。
確かに、私はnginx構成にそれほど精通しているわけではないので、nginxをWebsocketサーバーの逆プロキシとして機能させることさえ可能ですか?それとも、Nginxが新しいWebSocketのハンドシェイクのサポートを提供するのを待つ必要がありますか?ポート80でアプリサーバーとWebsocketサーバーの両方をリスニングすることが要件であると仮定すると、今のところNGINXなしで別のサーバーで薄く実行する必要があるということですか?
アドバイスや提案を前もってありがとう。 :)
- ジョン
解決
現在、Nginxを使用することはできませんもう真実ではない, 、しかし、私はHaproxyを見ることをお勧めします。私はまさにこの目的のためにそれを使用しました。
トリックは、ソケット接続が閉じられないように長いタイムアウトを設定することです。何かのようなもの:
timeout client 86400000 # In the frontend
timeout server 86400000 # In the backend
同じポートでレールとけいれんのアプリケーションを使用したい場合は、ACLルールを使用してWebSocket接続を検出し、別のバックエンドを使用できます。したがって、Haproxy FrontEndの構成は似ています
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
他のヒント
私を使うのはどうですか nginx_tcp_proxy_moduleモジュール?
このモジュールは、Nginxを使用した一般的なTCPプロキシ用に設計されています。 WebSocketにも適していると思います。そして、開発ブランチにTCP_SSL_MODULEを追加するだけです。
nginx(> = 1.3.13)がサポートされます 逆プロキシWebSockets。
# 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;
}
}
ボックス外(つまり、公式ソース)nginxは、上流(=バックエンド)へのHTTP 1.0接続のみを確立できます。 )そして接続を閉じます。それでおしまい。
これは、バックエンドへの永続的な接続を必要とする根本的な理由であり、nginxを介して動作しません(HTTP/1.1 = keepAliveなしでWebSocketがないと思います)。この欠点があるにもかかわらず、明らかな利点があります。NGINXは、いくつかの上流(負荷バランス)から選択でき、それらの一部が失敗した場合に備えて生き生きとしたものにフェイルオーバーすることができます。
編集: :NGINXは、バージョン1.1.4以降、HTTP 1.1をバックエンドおよびキープライブにサポートしています。 「FastCGI」および「プロキシ」の上流がサポートされています。 ここにドキュメントがあります
同じ問題について疑問に思っている人のために、Nginxは現在、HTTP 1.1の上流を正式にサポートしています。 「KeepAlive」および「Proxy_http_version 1.1」については、nginxドキュメントを参照してください。
新しいHTTPプッシュモジュールを使用したNginxはどうですか: http://pushmodule.slact.net/. 。逆プロキシで心配する必要があるかもしれない接続ジャグリング(いわば)の世話をします。それは確かに、まだ完全にはミックスに含まれていないWebSocketsの実行可能な代替品です。 HTTP Pushモジュールの開発者は、まだ完全に安定したバージョンで作業していることを知っていますが、アクティブな開発中です。生産コードベースで使用されているバージョンがあります。著者を引用するために、「退屈な名前の便利なツール」。
Nginxを使用して、長いポーリング接続を備えたComet Styleサーバーにプロキシを逆にしますが、うまく機能します。 proxy_send_timeoutとproxy_read_timeoutを適切な値に設定してください。また、NginxのプロキシモジュールがHTTP 1.1をまだ実行しているとは思わないため、NginxがHTTP 1.0をサポートするためにプロキシしているバックエンドサーバーを確認してください。
いくつかの回答で混乱を解消するために:KeepAliveを使用すると、クライアントが接続を再利用して別のHTTPリクエストを送信できます。元の質問が尋ねていたイベントが発生するまで、長いポーリングや接続を開いていることとは何の関係もありません。したがって、Nginxのプロキシモジュールは、KeepaliveがないHTTP 1.0のみをサポートしています。