WebSocket は、単一の TCP 接続を介した全二重通信をサポートする通信プロトコルです。 WebSocket は、永続的な接続を介してクライアントとサーバー間の双方向通信を確立するように設計されています。 WebSocket では、接続の作成または終了の頻度が低いため、オーバーヘッドが少なく、ネットワーク遅延も少なくて済みます。 従来の要求 - 応答 HTTP プロトコルと比較して、WebSocket はリアルタイムのインタラクションでより高い効率をサポートします。 WebSocket は、リアルタイム通信を必要とするシナリオに適しています。 Application Load Balancer (ALB) は、デフォルトで WebSocket をサポートしています。
WebSocket の概要
WebSocket を使用する理由
インターネット技術の急速な発展に伴い、Web アプリケーションは多様化しています。 ライブストリーミングチャットや弾幕など、一部のシナリオでは、サーバー側のリアルタイムプッシュが必要です。 従来のソリューションでは、ラウンドロビンアルゴリズムを使用して、1 秒などの一定の間隔でクライアントブラウザからサーバーへの HTTP リクエストを開始します。 次に、サーバーは最新のデータをクライアントに返します。 ただし、このソリューションには欠点があります。 クライアントは頻繁にリクエストを開始する必要があり、リクエストには大きな HTTP ヘッダーが含まれていますが、有用な情報は少なくなっています。 リクエストはサーバーの負荷を増大させるだけでなく、帯域幅リソースの大きな浪費にもつながります。
この問題に対処するために、HTML5 は WebSocket プロトコルを採用しています。これは、クライアントとサーバー間のより効率的な通信を確立します。 WebSocket は、クライアントとサーバー間の同時双方向通信を可能にする全二重通信をサポートしています。 これにより、サーバーはクライアント側のポーリングを必要とせずに、最新のデータをクライアントにプロアクティブにプッシュできます。 不要なリクエストが少ないため、双方向通信によりデータ交換の効率が大幅に向上し、サーバーと帯域幅リソースの消費が削減されると同時に、ユーザーによりスムーズなリアルタイムインタラクションが提供されます。
WebSocket の特性
WebSocket 接続を確立する前に、クライアントとサーバーは 3 ウェイ TCP ハンドシェイクと、ハンドシェイクとも呼ばれる特別な HTTP リクエストを実行して、HTTP 接続を WebSocket 接続にアップグレードする必要があります。 アップグレード中、クライアントとサーバーは HTTP ではなく WebSocket を介して通信します。 双方向通信は、同じ WebSocket 接続を介して確立できます。
WebSocket 接続が確立されると、接続は開いたままになり、双方向通信が可能になります。 WebSocket では、データ交換ごとに新しい接続を必要としたり、応答を待機したりする必要はありません。 WebSocket を介して確立された永続的で低遅延の接続により、データ交換の効率が大幅に向上します。
WebSocket は、データフレームとしてクライアントとサーバー間でデータを交換します。 WebSocket メッセージに必要なヘッダーは小さく、テキストまたはバイナリデータとして交換できます。 このタイプの通信により、永続的な接続のオーバーヘッドが削減され、データ交換の効率が向上します。 高パフォーマンスのリアルタイムインタラクションを提供しながら、サーバーと帯域幅のリソースをあまり必要としません。
WebSocket の詳細については、「The WebSocket Protocol」をご参照ください。
ユースケース
WebSocket は、AI アプリケーション、オンラインチャットルーム、リアルタイム通知システム、多人数参加型オンラインゲーム、リアルタイムメッセージプッシュなど、インスタントまたはリアルタイムの双方向通信を必要とするシナリオに適しています。
例
ある企業が Alibaba Cloud にオンラインチャットアプリケーションをデプロイしました。 ユーザーはドメイン名にアクセスしてバックエンドサーバーにアクセスできます。バックエンドサーバーでは、ユーザーが相互に対話できます。 アプリケーションは、ユーザー間の低遅延、高効率、双方向、リアルタイムのデータ交換をサポートするために、インスタント通信を必要とします。
高い同時実行性と永続的な接続管理が課題となっています。 ユーザー数が増加するにつれて、従来の HTTP モデルでは、多数のユーザーの同時リアルタイム通信をサポートできなくなります。 データ交換のたびに新しい接続が必要です。 このモデルは、サーバーの負荷を大幅に増加させ、サーバーのパフォーマンスを低下させます。
このシナリオでは、企業は ALB と WebSocket を一緒に使用して永続的な接続を管理し、高い同時実行性を維持できます。 企業は複数のバックエンドサーバーに WebSocket アプリケーションをデプロイし、Redis を使用してメッセージを同期できます。 このソリューションは、サービスの高可用性を確保し、オンラインチャットルームの信頼性が高く、効率的でリアルタイムのメッセージプッシュを可能にします。
使用上の注意
ALB の HTTP リスナーは、デフォルトで WebSocket をサポートしています。 また、ALB はローリングアップデートをサポートしています。 構成の変更は、既存の永続的な接続には影響しません。
ALB を使用する場合は、次の点に注意してください。
ALB とバックエンドサーバー間の接続を HTTP/1.1 などの特定のバージョンの HTTP を介して確立する場合、HTTP バージョンをサポートする Web サーバーをバックエンドサーバーとして使用することをお勧めします。
HTTP リスナーのデフォルトのタイムアウト期間は 60 秒です。 ALB がバックエンドサーバーと 60 秒間データを交換しないと、接続は閉じられます。
HTTP リスナーの [接続リクエストのタイムアウト] パラメーターの値を変更して、タイムアウト期間を任意の値に設定できます。
接続を維持するには、キープアライブメカニズムを使用して、60 秒ごとに ALB とバックエンドサーバー間でパケットを交換する必要があります。
前提条件
インターネット向け ALB インスタンスが作成されていること。 詳細については、「ALB インスタンスの作成と管理」をご参照ください。
3 つの Elastic Compute Service (ECS) インスタンスが作成されていること。 この例では、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 をデプロイおよび構成します。
# Extra Packages for Enterprise Linux (EPEL) をインストールします sudo yum install epel-release -y # Redis をインストールします sudo yum install redis -y # Redis を起動して有効にします sudo systemctl start redis sudo systemctl enable redis # Redis 構成ファイルを確認および変更して、リモート接続を許可します 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 # Redis を再起動して、構成の変更を適用します sudo systemctl restart redis # Redis が実行されているかどうかをクエリします 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 リクエストソース
[デフォルト] を選択します。
レコード値
CNAME、つまり ALB インスタンスのドメイン名を入力します。
TTL 期間
CNAME レコードが DNS サーバーにキャッシュされる生存時間 (TTL) 値を選択します。 この例では、デフォルト値が使用されます。
手順 5: 結果を確認する
異なる IP アドレスを持ち、インターネットアクセスをサポートする 2 台のコンピューターを準備します。 コンピューターのブラウザからメッセージを送信して、ALB インスタンスが WebSocket メッセージをリアルタイムでプッシュできるかどうかをテストします。
ブラウザから
http://ドメイン名:5000
にアクセスして、オンラインチャットルームにアクセスします。次の図は、チャットルームにアクセスできることを示しています。
ブラウザで開発者ツールを開くと、[ネットワーク] タブで WebSocket 通信が確立されていることがわかります。
ユーザー名を入力し、ユーザー名として設定 をクリックします。
メッセージを入力し、[送信] をクリックします。この操作を複数のコンピューターで繰り返します。
次の図は、異なるコンピューターからのメッセージがブラウザに表示されることを示しています。
前述のテストは、ALB が高可用性を維持しながら WebSocket メッセージをリアルタイムでプッシュできることを示しています。
FAQ
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 互換) とは を使用してアプリケーションの高可用性を向上させることをお勧めします。 詳細については、「概要」をご参照ください。