すべてのプロダクト
Search
ドキュメントセンター

Server Load Balancer:WebSocketを使用してリアルタイムメッセージングを有効にする

最終更新日:Sep 19, 2024

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を介して確立された永続的な低レイテンシ接続により、データ交換の効率が大幅に向上します。

image

WebSocketは、クライアントとサーバー間でデータをデータフレームとして交換します。 WebSocketメッセージは小さいヘッダーを必要とし、テキストまたはバイナリデータとして交換できます。 このタイプの通信は、永続的な接続のオーバーヘッドを削減し、データ交換の効率を向上させます。 必要なサーバーと帯域幅のリソースが少なく、高性能なリアルタイムインタラクションを提供します。

WebSocketの詳細については、「WebSocketプロトコル」をご参照ください。

シナリオの使用

WebSocketは、AIアプリケーション、オンラインチャットルーム、リアルタイム通知システム、マルチプレイオンラインゲーム、リアルタイムメッセージプッシュなど、即時またはリアルタイムの双方向通信を必要とするシナリオに適しています。

Alibaba Cloudにオンラインチャットアプリケーションをデプロイした企業。 ユーザーはドメイン名にアクセスしてバックエンドサーバーにアクセスできます。 アプリケーションは、ユーザー間の低遅延、高効率、双方向、およびリアルタイムのデータ交換をサポートするために、インスタント通信を必要とします。

高い並行性と永続的な接続管理が課題になります。 ユーザの数が増加するにつれて、従来のHTTPモデルは、もはや、多数のユーザに対する同時リアルタイム通信をサポートすることができない。 データ交換の各ラウンドには、新しい接続が必要です。 このモデルは、サーバーの負荷を大幅に増加させ、サーバーのパフォーマンスを低下させます。

このシナリオでは、ALBとWebSocketを使用して、永続的な接続を管理し、高い同時実行性を維持できます。 同社は、WebSocketアプリケーションを複数のバックエンドサーバーにデプロイし、Redisを使用してメッセージを同期できます。 このソリューションは、サービスの高可用性を保証し、オンラインチャットルームで信頼性が高く、効率的でリアルタイムのメッセージプッシュを可能にします。

image

使用上の注意

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) 番号が取得される。 詳細については、「ジェネリックドメイン名の登録」および「概要」をご参照ください。

手順

ステップ1: アプリケーションの展開

ECS03にRedisをデプロイし、ECS01およびECS02にWebSocketアプリケーションをデプロイします。

次の例は、テストオンラインチャットルームを展開する方法を示しています。 この例では、ECSインスタンスはCentOS 7.9オペレーティングシステムを使用します。 この例は参考用です。 プログラムとアプリケーションの設定を調整します。

ECS03へのRedisのデプロイ

  1. ECS03にログインします。

  2. 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
    
  3. 次の図に示すように、コマンドがエラーを報告せず、出力にRedisがアクティブ (実行中) 状態であることが示された場合、Redisがデプロイされ、設定が有効になります。

    image

ECS01にWebSocketアプリケーションをデプロイする

  1. ECS01にログインします。

  2. sudo pip3 install flask flask-socketio flask-cors redisコマンドを実行して、依存関係ライブラリをインストールします。

  3. vi ECS01_ws.pyコマンドを実行し、Iキーを押して編集モードに入ります。

  4. 次のコードをコピーして貼り付けます。

    テストアプリケーションを配置するためのサンプルコード

    説明

    13行目のredis_urlフィールドのIPアドレスを、ECS03のIPアドレスであるredisサーバーのIPアドレスに置き換えます。

    import os
    import redis
    from flask import Flask, render_template, request
    from flask_cors import CORS
    from flask_socketio import SocketIO, emit, disconnect
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    # Enable cross-origin resource sharing (CORS)
    CORS(app)
    
    # Configure Redis to manage queues and store states
    redis_url = "redis://192.168.*.*:6379/0"  # Replace the IP address with the IP address of your Redis server
    redis_client = redis.StrictRedis.from_url(redis_url)
    
    # Add the DEBUG log level to facilitate debugging
    socketio = SocketIO(app, message_queue=redis_url, manage_session=True, logger=True, engineio_logger=True, cors_allowed_origins="*")
    
    SESSION_PREFIX = "session:"
    
    
    def set_session_data(session_id, key, value):
        redis_client.hset(f"{SESSION_PREFIX}{session_id}", key, value)
    
    
    def get_session_data(session_id, key):
        return redis_client.hget(f"{SESSION_PREFIX}{session_id}", key)
    
    
    def delete_session_data(session_id):
        redis_client.delete(f"{SESSION_PREFIX}{session_id}")
    
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    
    @socketio.on('connect')
    def handle_connect():
        try:
            session_id = request.sid  # Obtain the client-side session ID
            print(f"Session {session_id} connected.")
            welcome_message = "Welcome to the chatroom!"
            emit('message', welcome_message)
            set_session_data(session_id, "username", '')  # The initialized username is empty
        except Exception as e:
            print(f"Error during connection: {str(e)}")
    
    
    @socketio.on('disconnect')
    def handle_disconnect():
        try:
            session_id = request.sid
            username = get_session_data(session_id, "username")
            if username:
                username = username.decode()
                leave_message = f"{username} left the chatroom."
                emit('message', leave_message, broadcast=True)
                print(leave_message)
            delete_session_data(session_id)
            print(f"Session {session_id} disconnected.")
        except Exception as e:
            print(f"Error during disconnection: {str(e)}")
    
    
    @socketio.on('set_username')
    def handle_set_username(username):
        session_id = request.sid
        set_session_data(session_id, "username", username)
        print(f"Set the username of the client {session_id} to {username}")
        emit('message', f"Your username is set to {username}")
    
    
    @socketio.on('message')
    def handle_message(msg):
        session_id = request.sid
        username = get_session_data(session_id, "username")
        if username:
            username = username.decode()
            formatted_message = f"{username}: {msg}"
            emit('message', formatted_message, broadcast=True)
            print(formatted_message)
        else:
            warning_message = "Failed to send the message. Specify a username first."
            emit('message', warning_message)
            print(warning_message)
    
    
    if __name__ == '__main__':
        # Store in the templates directory
        if not os.path.exists('templates'):
            os.makedirs('templates')
    
        # Use the Flask template (index.html)
        html_code = '''<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Chatroom</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                display: flex;
                flex-direction: column;
                align-items: center;
                margin: 0;
                padding: 0;
                background-color: #f0f0f0;
            }
            h1 {
                color: #333;
            }
            .chat-container {
                width: 90%;
                max-width: 600px;
                background: white;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            }
            .user-container, .message-container {
                display: flex;
                margin-bottom: 10px;
            }
            .user-container input, .message-container input {
                flex: 1;
                padding: 10px;
                margin-right: 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            .message-container {
                margin-top: 10px;
            }
            button {
                padding: 10px;
                background-color: #0056b3;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
            }
            button:hover {
                background-color: #004099;
            }
            #messages {
                border: 1px solid #ccc;
                padding: 10px;
                height: 300px;
                overflow-y: scroll;
                margin-bottom: 10px;
                border-radius: 4px;
                background-color: #f9f9f9;
            }
        </style>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <h1>Online Chatroom</h1>
        <div class="chat-container">
            <div class="user-container">
                <input type="text" id="username" autocomplete="off" placeholder="Enter a username">
                <button onclick="setUsername()">Set as Username</button>
            </div>
            <div id="messages"></div>
            <div class="message-container">
                <input type="text" id="myMessage" autocomplete="off" placeholder="Enter a message...">
                <button onclick="sendMessage()">Send</button>
            </div>
        </div>
        <script>
            var socket = io({ transports: ['websocket', 'polling', 'flashsocket'] });
            var usernameSet = false;
            socket.on('connect', function() {
                console.log("Connected to the server!");
                socket.on('message', function(msg){
                    $('#messages').append($('<div>').text(msg));
                    $('#messages').scrollTop($('#messages')[0].scrollHeight);
                });
            });
            function setUsername() {
                var username = $('#username').val();
                if (username) {
                    socket.emit('set_username', username);
                    usernameSet = true;  // Enter a username identifier
                } else {
                    alert("The username cannot be empty.");
                }
            }
            function sendMessage() {
                if (usernameSet) {
                    var message = $('#myMessage').val();
                    if (message) {
                        socket.send(message);
                        $('#myMessage').val('');
                    } else {
                        alert("The message cannot be empty.");
                    }
                } else {
                    alert("Specify a username first.");
                }
            }
        </script>
    </body>
    </html>
    '''
    
        # Save the template as a file
        with open('templates/index.html', 'w') as file:
            file.write(html_code)
    
        socketio.run(app, host='0.0.0.0', port=5000)
    

  5. [Esc] キーを押して :wqと入力し、設定を保存します。

  6. sudo python3 ECS01_ws.pyコマンドを実行して、スクリプトを実行します。

  7. 次の出力は、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アプリケーションをデプロイする

  1. ECS02にログインします。

  2. sudo pip3 install flask flask-socketio flask-cors redisコマンドを実行して、依存関係ライブラリをインストールします。

  3. vi ECS02_ws.pyコマンドを実行し、Iキーを押して編集モードに入ります。

  4. 次のコードをコピーして貼り付けます。

    テストアプリケーションを配置するためのサンプルコード

    説明

    13行目のredis_urlフィールドのIPアドレスを、ECS03のIPアドレスであるredisサーバーのIPアドレスに置き換えます。

    import os
    import redis
    from flask import Flask, render_template, request
    from flask_cors import CORS
    from flask_socketio import SocketIO, emit, disconnect
    
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    # Enable cross-origin resource sharing (CORS)
    CORS(app)
    
    # Configure Redis to manage queues and store states
    redis_url = "redis://192.168.*.*:6379/0"  # Replace the IP address with the IP address of your Redis server
    redis_client = redis.StrictRedis.from_url(redis_url)
    
    # Add the DEBUG log level to facilitate debugging
    socketio = SocketIO(app, message_queue=redis_url, manage_session=True, logger=True, engineio_logger=True, cors_allowed_origins="*")
    
    SESSION_PREFIX = "session:"
    
    
    def set_session_data(session_id, key, value):
        redis_client.hset(f"{SESSION_PREFIX}{session_id}", key, value)
    
    
    def get_session_data(session_id, key):
        return redis_client.hget(f"{SESSION_PREFIX}{session_id}", key)
    
    
    def delete_session_data(session_id):
        redis_client.delete(f"{SESSION_PREFIX}{session_id}")
    
    
    @app.route('/')
    def index():
        return render_template('index.html')
    
    
    @socketio.on('connect')
    def handle_connect():
        try:
            session_id = request.sid  # Obtain the client-side session ID
            print(f"Session {session_id} connected.")
            welcome_message = "Welcome to the chatroom!"
            emit('message', welcome_message)
            set_session_data(session_id, "username", '')  # The initialized username is empty
        except Exception as e:
            print(f"Error during connection: {str(e)}")
    
    
    @socketio.on('disconnect')
    def handle_disconnect():
        try:
            session_id = request.sid
            username = get_session_data(session_id, "username")
            if username:
                username = username.decode()
                leave_message = f"{username} left the chatroom."
                emit('message', leave_message, broadcast=True)
                print(leave_message)
            delete_session_data(session_id)
            print(f"Session {session_id} disconnected.")
        except Exception as e:
            print(f"Error during disconnection: {str(e)}")
    
    
    @socketio.on('set_username')
    def handle_set_username(username):
        session_id = request.sid
        set_session_data(session_id, "username", username)
        print(f"Set the username of the client {session_id} to {username}")
        emit('message', f"Your username is set to {username}")
    
    
    @socketio.on('message')
    def handle_message(msg):
        session_id = request.sid
        username = get_session_data(session_id, "username")
        if username:
            username = username.decode()
            formatted_message = f"{username}: {msg}"
            emit('message', formatted_message, broadcast=True)
            print(formatted_message)
        else:
            warning_message = "Failed to send the message. Specify a username first."
            emit('message', warning_message)
            print(warning_message)
    
    
    if __name__ == '__main__':
        # Store in the templates directory
        if not os.path.exists('templates'):
            os.makedirs('templates')
    
        # Use the Flask template (index.html)
        html_code = '''<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Chatroom</title>
        <style>
            body {
                font-family: Arial, sans-serif;
                display: flex;
                flex-direction: column;
                align-items: center;
                margin: 0;
                padding: 0;
                background-color: #f0f0f0;
            }
            h1 {
                color: #333;
            }
            .chat-container {
                width: 90%;
                max-width: 600px;
                background: white;
                padding: 20px;
                border-radius: 8px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
            }
            .user-container, .message-container {
                display: flex;
                margin-bottom: 10px;
            }
            .user-container input, .message-container input {
                flex: 1;
                padding: 10px;
                margin-right: 10px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
            .message-container {
                margin-top: 10px;
            }
            button {
                padding: 10px;
                background-color: #0056b3;
                color: white;
                border: none;
                border-radius: 4px;
                cursor: pointer;
            }
            button:hover {
                background-color: #004099;
            }
            #messages {
                border: 1px solid #ccc;
                padding: 10px;
                height: 300px;
                overflow-y: scroll;
                margin-bottom: 10px;
                border-radius: 4px;
                background-color: #f9f9f9;
            }
        </style>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js"></script>
        <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <h1>Online Chatroom</h1>
        <div class="chat-container">
            <div class="user-container">
                <input type="text" id="username" autocomplete="off" placeholder="Enter a username">
                <button onclick="setUsername()">Set as Username</button>
            </div>
            <div id="messages"></div>
            <div class="message-container">
                <input type="text" id="myMessage" autocomplete="off" placeholder="Enter a message...">
                <button onclick="sendMessage()">Send</button>
            </div>
        </div>
        <script>
            var socket = io({ transports: ['websocket', 'polling', 'flashsocket'] });
            var usernameSet = false;
            socket.on('connect', function() {
                console.log("Connected to the server!");
                socket.on('message', function(msg){
                    $('#messages').append($('<div>').text(msg));
                    $('#messages').scrollTop($('#messages')[0].scrollHeight);
                });
            });
            function setUsername() {
                var username = $('#username').val();
                if (username) {
                    socket.emit('set_username', username);
                    usernameSet = true;  // Enter a username identifier
                } else {
                    alert("The username cannot be empty.");
                }
            }
            function sendMessage() {
                if (usernameSet) {
                    var message = $('#myMessage').val();
                    if (message) {
                        socket.send(message);
                        $('#myMessage').val('');
                    } else {
                        alert("The message cannot be empty.");
                    }
                } else {
                    alert("Specify a username first.");
                }
            }
        </script>
    </body>
    </html>
    '''
    
        # Save the template as a file
        with open('templates/index.html', 'w') as file:
            file.write(html_code)
    
        socketio.run(app, host='0.0.0.0', port=5000)
    

  5. [Esc] キーを押して :wqと入力し、設定を保存します。

  6. sudo python3 ECS02_ws.pコマンドを実行してスクリプトを実行します。

  7. 次の出力は、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: サーバーグループの設定

  1. ALB コンソールにログインします。

  2. 上部のナビゲーションバーで、ALBインスタンスがデプロイされているリージョンを選択します。

  3. 左側のナビゲーションウィンドウで、[サーバーグループ] をクリックします。

  4. [サーバーグループ] ページで、[サーバーグループの作成] をクリックします。 [サーバーグループの作成] ダイアログボックスでパラメーターを設定し、[作成] をクリックします。 次の表に、一部のパラメーターのみを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。

    パラメーター

    説明

    サーバーグループタイプ

    作成するサーバーグループのタイプを選択します。

    [VPC]

    ECS01およびECS02の仮想プライベートクラウド (VPC) を選択します。

    ALBインスタンスとバックエンドサーバーは同じVPCにある必要があります。

  5. [サーバーグループが作成されました] メッセージで、[バックエンドサーバーの追加] をクリックします。

  6. バックエンドサーバーの追加ウィザードで、バックエンドサーバーとしてECS01とECS02を追加します。 ポートをWebSocketアプリケーションのポートに設定します。 この例では、WebSocketアプリケーションはポート5000を使用します。

手順3: HTTPリスナーの追加

  1. ALB コンソールにログインします。

  2. 上部のナビゲーションバーで、ALBインスタンスがデプロイされているリージョンを選択します。

  3. 左側のメニュで、インスタンスをクリックします。

  4. [インスタンス] ページで、ALBインスタンスを見つけ、[操作] 列の [リスナーの作成] をクリックします。

  5. [リスナーの設定] ステップで、パラメーターを設定します。 次の表に、いくつかのパラメーターを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。 パラメーターを設定したら、[次へ] をクリックします。

    パラメーター

    説明

    リスナープロトコル

    [HTTP] を選択します。

    リスナーポート

    この例では、ポート5000が使用される。

  6. [サーバーグループの選択] ステップで、パラメーターを設定します。 次の表に、いくつかのパラメーターを示します。 ビジネス要件に基づいて他のパラメーターを設定するか、デフォルト値を使用します。 パラメーターを設定したら、[次へ] をクリックします。

    パラメーター

    説明

    サーバーグループ

    サーバーグループを選択します。

  7. [設定の確認] ステップで、パラメーターが有効かどうかを確認し、[送信] をクリックします。

ステップ4: DNSレコードの追加

  1. ALB コンソールにログインします。

  2. 上部のナビゲーションバーで、ALBインスタンスがデプロイされているリージョンを選択します。

  3. DNSレコードを追加するALBインスタンスを見つけ、ドメイン名をコピーします。

  4. CNAMEレコードを作成するには、次の手順を実行します。

    1. Alibaba Cloud DNS コンソールにログオンします。

    2. [ドメイン名の解決] ページで、[ドメイン名の追加] をクリックします。

    3. [ドメイン名の追加] ダイアログボックスで、ホストのドメイン名を入力し、[OK] をクリックします。

      重要

      CNAMEレコードを作成する前に、TXTレコードを使用してドメイン名の所有権を確認する必要があります。

    4. 管理するドメイン名を見つけて、[操作] 列の [DNS設定] をクリックします。

    5. [DNS 設定] ページで、[レコードの追加] をクリックします。

    6. [DNSレコードの追加] パネルでパラメーターを設定し、[OK] をクリックします。 下表に、各パラメーターを説明します。

      パラメーター

      説明

      レコードタイプ

      ドロップダウンリストから [CNAME] を選択します。

      ホスト名

      ドメイン名のプレフィックスを入力します。

      DNSリクエストソース

      [デフォルト] を選択します。

      レコード値

      ALBインスタンスのドメイン名であるCNAMEを入力します。

      TTL

      DNSサーバーにキャッシュされるCNAMEレコードの有効期限 (TTL) 値を選択します。 この例では、デフォルト値が使用されます。

ステップ5: Verify the result

異なるIPアドレスを持ち、インターネットアクセスをサポートする2台のコンピューターを準備します。 コンピューター上のブラウザーからメッセージを送信して、ALBインスタンスがWebSocketメッセージをリアルタイムでプッシュできるかどうかをテストします。

  1. ブラウザからhttp:// Domain name:5000にアクセスして、オンラインチャットルームにアクセスします。

    次の図は、チャットルームにアクセスできることを示しています。

    image

    ブラウザで開発者ツールを開くと、[ネットワーク] タブでWebSocket通信が確立されていることがわかります。

    image

  2. ユーザー名を入力し、[ユーザー名として設定] をクリックします。

  3. メッセージを入力し、[送信] をクリックします。 この操作を複数のコンピューターで繰り返します。

    次の図は、異なるコンピュータからのメッセージがブラウザに表示されることを示しています。

    image

  4. 上記のテストでは、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) が発生する可能性があります。 本番環境では、アプリケーションの高可用性を向上させるためにApsaraDB for Redisを使用することを推奨します。 詳細については、「概要」をご参照ください。