nginxプロキシsocket.ioサービスの落とし穴の詳細な説明

nginxプロキシsocket.ioサービスの落とし穴の詳細な説明

Nginx は 2 つの socket.io サーバーをプロキシします。 socket.ioの動作モードはポーリングからwebsocketにアップグレードされました

現象

nginx 経由でサービスをリクエストすると、大量の 400 エラーが発生していました。Websocket にアップグレードできる場合もあれば、エラーが報告され続ける場合もありました。ただし、 ip+端口を介して直接アクセスすると、100% 成功します。

分析する

シド

SID が私たちの問題の鍵です。最初に接続を作成するとき (ポーリング モードは長い接続をシミュレートします)、クライアントは次のような要求を開始します。

https://***/?EIO=3&transport=polling&t=1540820717277-0

メッセージを受信した後、サーバーはオブジェクトを作成し、それを接続にバインドし、セッションをマークするための sid (セッション ID) を返します。セッションとは何を意味するのでしょうか? セッションとは一連のインタラクションであり、これらのインタラクションは相互に関連しています。このシナリオでは、次の http リクエストが来たときに、以前に理論上の長い接続にバインドされていたオブジェクトを見つける必要があります (ここでは Websocket がないので、理論上のものです)。 HTTP リクエストはステートレスであり、各リクエストは独立していることがわかっているので、socket.io ではこれを実現するために SID を導入しています。リクエストを受信すると、サーバーは sid を生成し、応答を確認します。

次のようにコードをコピーします
{"sid":"EoGaL3fRQlpTOaLp5eST","アップグレード":["websocket"],"pingInterval":8000,"pingTimeout":10000}

後続の各リクエストでは、Websocket リクエストを確立するためのリクエストも含め、この sid を送信する必要があります。したがって、sid はポーリングとポーリングを Websocket にアップグレードするための鍵となります。この後のリクエストは次のようになります。

https://***/?EIO=3&transport=polling&t=1540820717314-1&sid=EoGaL3fRQlpTOaLp5eST

または

wss://***/?EIO=3&transport=websocket&t=1540820717314-1&sid=EoGaL3fRQlpTOaLp5eST

そこで疑問になるのが、リクエストに含まれる SID がサーバーによって生成されなかった場合はどうなるかということです。サーバーはそれを認識せず、400を返し、

無効なSID

これが私たちが遭遇した問題です。nginx のデフォルトの負荷分散戦略はポーリングなので、リクエストは SID を生成したマシンではないマシンでヒットする可能性があります。この時点で、400 を受け取ります。運が良ければ、元のマシンでもヒットする可能性があります。さらに運が良ければ、Websocket 接続が確立されるまで持続することもできます。

解決する

ここに2つの解決策があります

  1. Nginx は負荷分散に ip_hash を使用し、クライアントからのすべてのリクエストが 1 つのサーバーに送信されるようにします。
  2. ポーリングモードは使用せず、WebSocketのみを使用してください

どちらの選択肢にも長所と短所があります。 2 番目は明らかで、Websocket をサポートしていない古いブラウザやクライアントは動作しません。最初の問題は、より隠れたものです。マシンを追加または削除するとどうなるか想像してみてください。このとき、ip_hash 戦略のモデルが変更され、以前の接続はすべて無効になります。ただし、マイクロサービスの場合、スケーリングは非常に頻繁に行われる操作であり (特に製品が開発段階にある場合)、このような損失のあるスケーリングはおそらく受け入れられません。

まとめると、websocket を直接使用することをお勧めします。結局のところ、websocket をサポートしていない古いバージョンはわずかな割合を占めており、最初にポーリングするよりも時間がかかりません。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • nginxリバースプロキシwebSocket設定の詳細な説明
  • Nginx リバース プロキシ WebSocket 応答 403 の解決方法の詳細な説明
  • Nginx 実戦リバースプロキシ WebSocket 構成例
  • Nginx を WebSocket プロキシとして使用するチュートリアル
  • Nginx リバース プロキシ Websocket 構成例

<<:  Vue SPA ファースト スクリーン最適化ソリューション

>>:  mysql data_dirの変更によって発生するエラー問題を解決する

推薦する

IE8 ベータ 1 には注意が必要な 2 つの領域があります

<br />関連記事: Web スキル: 複数の IE バージョンを共存させるソリューシ...

Reactは適応性の高い仮想リストを実装する

目次変換前:変換後: 0x0の基本0x1 「固定高さ」の仮想リストを実装する原理:最適化: 0x2 ...

Mysql の一般的なベンチマーク コマンドの概要

mysqlslap共通パラメータの説明–auto-generate-sql システムはテスト用のSQ...

HTML 順序なしリスト 箇条書き 画像を使用した CSS の記述

少なくとも 5 冊のベストセラー書籍の順序なしリストを含む HTML ページを作成します。各書籍の前...

Navicat を MySQL に接続するときに発生する 2059 エラーの解決方法

最近、Djangoを学習しているときにデータベースを使用する必要があったため、MySQLで使用するた...

mysql bin-log ログファイルを sql ファイルに変換する方法

mysqlbinlogのバージョンを表示mysqlbinlog -V [--version] bin...

Vue+webrtc (Tencent Cloud) ライブブロードキャスト機能の実装実践

目次1. 生放送効果2. ライブストリーミングを開始する手順2.1 Tencent Web(高速ライ...

mysql5.7.22 ダウンロードプロセス図

1. 公式ウェブサイト www.mysql.com にアクセスし、ダウンロードを選択します。 2. ...

CentOS 7.x に ZSH ターミナルをインストールする方法

1. 基本コンポーネントをインストールするまず、 yumコマンドを実行して、コードpullために必要...

js はマウスインとマウスアウトによるカード切り替えコンテンツを実装します

この記事では、マウスでカード内外のコンテンツを切り替えるためのjsの具体的なコードを紹介します。具体...

Access_Tokenの統合管理を実現するミニプログラム開発

目次TOKEN タイマーリフレッシュ2. access_tokenの内部設計2.1 access_t...

dockerプライベート倉庫の構築と利用の詳細説明

1. リポジトリイメージをダウンロードする docker プルレジストリ 2. プライベートウェアハ...

Windows 10 での MySQL 8.0.12 解凍バージョンのインストール グラフィック チュートリアル

この記事は、MySQL 8.0.12解凍版のインストールグラフィックチュートリアルを記録しています。...

MySQLステートメントの記述と実行順序を理解するだけです

MySQL ステートメントの書き込み順序と実行順序には大きな違いがあります。書き順、mysql の一...

Alibaba Cloud イメージリポジトリの Docker 構成変更の実装

docker リポジトリ自体は非常に遅いですが、中国の Alibaba Cloud ミラー リポジト...