WebSocketは、単一のTCP接続を介した全二重通信をサポートする通信プロトコルです。 WebSocketは、永続的な接続を介してクライアントとサーバー間の双方向通信を確立するように設計されています。 WebSocketは、接続の作成またはクローズの頻度が少ないため、必要なオーバーヘッドが少なく、ネットワークの待ち時間が短くなります。 従来のリクエスト-レスポンスHTTPプロトコルと比較して、WebSocketはリアルタイムでのやり取りの効率を向上させます。 WebSocketは、リアルタイム通信が必要なシナリオに適しています。 Application Load Balancer (ALB) は、デフォルトでWebSocketをサポートしています。
WebSocketの概要
なぜWebSocket?
インターネット技術の急速な発展に伴い、webアプリケーションはより多様化しています。 ライブストリーミングチャットやライブコメントなどの一部のシナリオでは、サーバー側のリアルタイムプッシュが必要です。 従来のソリューションでは、ラウンドロビンアルゴリズムを使用して、1秒などの固定間隔でクライアントブラウザからサーバへのHTTP要求を開始します。 そして、サーバは、最新のデータをクライアントに返す。 しかしながら、この解決策には欠点がある。 クライアントは頻繁にリクエストを開始する必要があります。リクエストには大きなHTTPヘッダーが含まれていますが、情報はあまり役に立ちません。 この要求は、サーバの負荷を増大させるだけでなく、帯域幅リソースの著しい浪費を引き起こす。
この問題に対処するために、HTML5はWebSocketプロトコルを採用しており、クライアントとサーバー間でより効率的な通信を確立します。 WebSocketは、クライアントとサーバー間の同時双方向通信を可能にする全二重通信をサポートします。 これにより、サーバーはクライアント側のポーリングを必要とせずに、最新のデータをクライアントにプロアクティブにプッシュできます。 不要なリクエストが少なくなるため、双方向通信はデータ交換の効率を大幅に向上させ、サーバーと帯域幅のリソースの消費を削減しながら、よりスムーズなリアルタイムインタラクションをユーザーに提供します。
WebSocketの特性
WebSocket接続を確立する前に、クライアントとサーバーは、HTTP接続をWebSocket接続にアップグレードするために、3方向TCPハンドシェイクと、ハンドシェイクとも呼ばれる特別なHTTP要求を完了する必要があります。 アップグレード中、クライアントとサーバーはHTTPではなくWebSocketを介して通信します。 同じWebSocket接続で双方向通信を確立できます。
WebSocket接続が確立された後も、ソケットと同様の双方向通信を可能にするために開いたままになります。 WebSocketは、新しい接続を必要とせず、データ交換の各ラウンドの応答を待機しません。 WebSocketを介して確立された永続的な低レイテンシ接続により、データ交換の効率が大幅に向上します。
WebSocketは、クライアントとサーバー間でデータをデータフレームとして交換します。 WebSocketメッセージは小さいヘッダーを必要とし、テキストまたはバイナリデータとして交換できます。 このタイプの通信は、永続的な接続のオーバーヘッドを削減し、データ交換の効率を向上させます。 必要なサーバーと帯域幅のリソースが少なく、高性能なリアルタイムインタラクションを提供します。
WebSocketの詳細については、「WebSocketプロトコル」をご参照ください。
適用シナリオ
WebSocketは、AIアプリケーション、オンラインチャットルーム、リアルタイム通知システム、マルチプレイオンラインゲーム、リアルタイムメッセージプッシュなど、即時またはリアルタイムの双方向通信を必要とするシナリオに適しています。
例
Alibaba Cloudにオンラインチャットアプリケーションをデプロイした企業。 ユーザーはドメイン名にアクセスしてバックエンドサーバーにアクセスできます。 アプリケーションは、ユーザー間の低遅延、高効率、双方向、およびリアルタイムのデータ交換をサポートするために、インスタント通信を必要とします。
高い並行性と永続的な接続管理が課題になります。 ユーザの数が増加するにつれて、従来のHTTPモデルは、もはや、多数のユーザに対する同時リアルタイム通信をサポートすることができない。 データ交換の各ラウンドには、新しい接続が必要です。 このモデルは、サーバーの負荷を大幅に増加させ、サーバーのパフォーマンスを低下させます。
このシナリオでは、ALBとWebSocketを使用して、永続的な接続を管理し、高い同時実行性を維持できます。 同社は、WebSocketアプリケーションを複数のバックエンドサーバーにデプロイし、Redisを使用してメッセージを同期できます。 このソリューションは、サービスの高可用性を保証し、オンラインチャットルームで信頼性が高く、効率的でリアルタイムのメッセージプッシュを可能にします。
使用上の注意
ALBのHTTPリスナーはデフォルトでWebSocketをサポートしています。 さらに、ALBはローリング更新をサポートします。 構成の変更は、既存の永続接続には影響しません。
ALBを使用する場合は、次の項目に注意してください。
HTTP/1.1など、特定のバージョンのHTTPを介してALBとバックエンドサーバー間の接続を確立する場合は、HTTPバージョンをサポートするwebサーバーをバックエンドサーバーとして使用することを推奨します。
HTTPリスナーのデフォルトのタイムアウト時間は60秒です。 ALBがバックエンドサーバーと60秒間データを交換しない場合、接続は閉じられます。
HTTPリスナーの [Connection Request Timeout] パラメーターの値を変更して、タイムアウト期間を所望の値に設定できます。
接続を維持するには、キープアライブメカニズムを使用して、ALBとバックエンドサーバー間で60秒ごとにパケットを交換する必要があります。
前提条件
インターネット接続のALBインスタンスが作成されます。 詳細については、「ALBインスタンスの作成」をご参照ください。
3つのECS (Elastic Compute Service) インスタンスが作成されます。 この例では、ECSインスタンスの名前はECS01、ECS02、およびECS03です。
WebSocketアプリケーションは、ECS01およびECS02にデプロイされます。 RedisはECS03にデプロイされています。
この例では、すべてのECSインスタンスがCentOS 7.9オペレーティングシステムを使用しています。
ECS01、ECS02、およびECS03を同じセキュリティグループに追加することを推奨します。 ECSインスタンスを異なるセキュリティグループに追加する場合は、相互に通信ポートへのアクセスを許可する必要があります。
ドメイン名が登録され、そのドメイン名に対してインターネットコンテンツプロバイダ (ICP) 番号が取得される。 詳細については、「ジェネリックドメイン名の登録」および「ICP登録プロセス」をご参照ください。
手順
ステップ1: アプリケーションの展開
ECS03にRedisをデプロイし、ECS01およびECS02にWebSocketアプリケーションをデプロイします。
次の例は、テストオンラインチャットルームを展開する方法を示しています。 この例では、ECSインスタンスはCentOS 7.9オペレーティングシステムを使用します。 この例は参考用です。 プログラムとアプリケーションの設定を調整します。
ECS03へのRedisのデプロイ
ECS03にログインします。
ECS03で次のコマンドを実行して、Redisをデプロイおよび設定します。
# Install Extra Packages for Enterprise Linux (EPEL) sudo yum install epel-release -y # Install Redis sudo yum install redis -y # Start and enable Redis sudo systemctl start redis sudo systemctl enable redis # Check and modify the Redis configuration file to allow remote connections sudo sed -i 's/^bind 127.0.0.1$/bind 0.0.0.0/' /etc/redis.conf sudo sed -i 's/^protected-mode yes/protected-mode no/' /etc/redis.conf # Restart Redis to apply the configuration modifications sudo systemctl restart redis # Query whether Redis is running sudo systemctl status redis
次の図に示すように、コマンドがエラーを報告せず、出力にRedisがアクティブ (実行中) 状態であることが示された場合、Redisがデプロイされ、設定が有効になります。
ECS01にWebSocketアプリケーションをデプロイする
ECS01にログインします。
sudo pip3 install flask flask-socketio flask-cors redis
コマンドを実行して、依存関係ライブラリをインストールします。vi ECS01_ws.py
コマンドを実行し、I
キーを押して編集モードに入ります。次のコードをコピーして貼り付けます。
[Esc]
キーを押して:wq
と入力し、設定を保存します。sudo python3 ECS01_ws.py
コマンドを実行して、スクリプトを実行します。次の出力は、WebSocketアプリケーションが有効であり、ポート5000を使用していることを示します。
Server initialized for threading. * Serving Flask app 'ECS01_ws' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. * Running on http://192.168.*.*:5000/ (Press CTRL+C to quit)
WebSocketアプリケーションの有効化に失敗した場合は、指定したポートが他のアプリケーションによって占有されているか、コマンドまたはコードにエラーがあるかどうかを確認してください。
ECS02にWebSocketアプリケーションをデプロイする
ECS02にログインします。
sudo pip3 install flask flask-socketio flask-cors redis
コマンドを実行して、依存関係ライブラリをインストールします。vi ECS02_ws.py
コマンドを実行し、I
キーを押して編集モードに入ります。次のコードをコピーして貼り付けます。
[Esc]
キーを押して:wq
と入力し、設定を保存します。sudo python3 ECS02_ws.p
コマンドを実行してスクリプトを実行します。次の出力は、WebSocketアプリケーションが有効であり、ポート5000を使用していることを示します。
Server initialized for threading. * Serving Flask app 'ECS02_ws' (lazy loading) * Environment: production WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Debug mode: off * Running on all addresses. WARNING: This is a development server. Do not use it in a production deployment. * Running on http://192.168.*.*:5000/ (Press CTRL+C to quit)
WebSocketアプリケーションの有効化に失敗した場合は、指定したポートが他のアプリケーションによって占有されているか、コマンドまたはコードにエラーがあるかどうかを確認してください。
手順2: サーバーグループの設定
ALB コンソールにログインします。
上部のナビゲーションバーで、ALBインスタンスがデプロイされているリージョンを選択します。
左側のナビゲーションウィンドウで、[サーバーグループ] をクリックします。
[サーバーグループ] ページで、[サーバーグループの作成] をクリックします。 [サーバーグループの作成] ダイアログボックスでパラメーターを設定し、[作成] をクリックします。 次の表に、一部のパラメーターのみを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。
パラメーター
説明
サーバーグループタイプ
作成するサーバーグループのタイプを選択します。
[VPC]
ECS01およびECS02の仮想プライベートクラウド (VPC) を選択します。
ALBインスタンスとバックエンドサーバーは同じVPCにある必要があります。
[サーバーグループが作成されました] メッセージで、[バックエンドサーバーの追加] をクリックします。
バックエンドサーバーの追加ウィザードで、バックエンドサーバーとしてECS01とECS02を追加します。 ポートをWebSocketアプリケーションのポートに設定します。 この例では、WebSocketアプリケーションはポート5000を使用します。
手順3: HTTPリスナーの追加
ALB コンソールにログインします。
上部のナビゲーションバーで、ALBインスタンスがデプロイされているリージョンを選択します。
左側のメニュで、インスタンスをクリックします。
[インスタンス] ページで、ALBインスタンスを見つけ、[操作] 列の [リスナーの作成] をクリックします。
[リスナーの設定] ステップで、パラメーターを設定します。 次の表に、いくつかのパラメーターを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。 パラメーターを設定したら、[次へ] をクリックします。
パラメーター
説明
リスナープロトコル
[HTTP] を選択します。
リスナーポート
この例では、ポート5000が使用される。
[サーバーグループの選択] ステップで、パラメーターを設定します。 次の表に、いくつかのパラメーターを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。 パラメーターを設定したら、[次へ] をクリックします。
パラメーター
説明
サーバーグループ
サーバーグループを選択します。
[設定の確認] ステップで、パラメーターが有効かどうかを確認し、[送信] をクリックします。
ステップ4: DNSレコードの追加
実際のビジネスシナリオでは、CNAMEレコードを使用して、カスタムドメイン名をALBインスタンスのドメイン名にマップすることを推奨します。
左側のナビゲーションウィンドウで、
を選択します。インスタンスページで、ALBインスタンスのドメイン名をコピーします。
CNAMEレコードを作成するには、次の手順を実行します。
説明ドメイン名がAlibaba Cloudドメインを使用して登録されていない場合、DNSレコードを設定する前にドメイン名をAlibaba Cloud DNSに追加する必要があります。 詳細については、「ドメイン名の管理」をご参照ください。
Alibaba Cloud DNSコンソールにログインします。
権威DNS解決ページ、ドメイン名を見つけて、アクション列のDNS設定をクリックします。
ドメイン名の詳細ページのDNS設定タブで、DNSレコードの追加をクリックします。
[DNSレコードの追加] パネルでパラメーターを設定し、[OK] をクリックします。 下表にパラメーターを示します。
パラメーター
説明
レコードタイプ
ドロップダウンリストから [CNAME] を選択します。
ホスト名
ドメイン名のプレフィックスを入力します。 この例では、@ を入力します。
説明ルートドメイン名を使用する場合は、
@
と入力します。DNSリクエストソース
[デフォルト] を選択します。
レコード値
ALBインスタンスのドメイン名であるCNAMEを入力します。
TTL
DNSサーバーにキャッシュされるCNAMEレコードの有効期限 (TTL) 値を選択します。 この例では、デフォルト値が使用されます。
ステップ5: Verify the result
異なるIPアドレスを持ち、インターネットアクセスをサポートする2台のコンピューターを準備します。 コンピューター上のブラウザーからメッセージを送信して、ALBインスタンスがWebSocketメッセージをリアルタイムでプッシュできるかどうかをテストします。
ブラウザから
http:// Domain name:5000
にアクセスして、オンラインチャットルームにアクセスします。次の図は、チャットルームにアクセスできることを示しています。
ブラウザで開発者ツールを開くと、[ネットワーク] タブでWebSocket通信が確立されていることがわかります。
ユーザー名を入力し、[ユーザー名として設定] をクリックします。
メッセージを入力し、[送信] をクリックします。 この操作を複数のコンピューターで繰り返します。
次の図は、異なるコンピュータからのメッセージがブラウザに表示されることを示しています。
上記のテストでは、ALBが高可用性を維持しながらWebSocketメッセージをリアルタイムでプッシュできることを示しています。
よくある質問
WebSocket Secureプロトコルの使用方法?
WebSocket Secureは、WebSocketの暗号化バージョンです。
デフォルトでは、HTTPSリスナーはWebSocket Secureをサポートしています。 WebSocket Secureを有効にするには、HTTPSリスナーを作成します。
WebSocketの使用に対して課金されますか?
WebSocketまたはWebSocket Secureの使用に対して課金されません。
WebSocketをサポートしているリージョン
WebSocketとWebSocket Secureは、ALBのすべてのリージョンでサポートされています。
関連ドキュメント
テストを容易にするために、このトピックでは簡単な例を使用して、ECSインスタンスにRedisをデプロイする方法について説明します。 ただし、Redisサーバーエラーにより、単一障害点 (SPOF) が発生する可能性があります。 本番環境では、Tair (Redis OSS互換) とは何ですか? アプリケーションの高可用性を向上させます。 詳細については、「概要」をご参照ください。