この記事は、Bilibili の上級開発エンジニアである Huang Shancheng によって共有されました。元のタイトルは「Ten Thousands of Long-term Message System」でした。この記事は、タイプセットされ、内容が最適化されました。
1 はじめに
今日のデジタル エンターテインメント時代において、弾幕はライブ ブロードキャスト プラットフォームに不可欠なインタラクティブ要素の 1 つとなっています。

ユーザーは、集中砲火やギフトの送信などを行うことで、ライブ配信画面上に自分の感想やコメント、インタラクティブなコンテンツをリアルタイムに表示することができ、ユーザーの視聴体験をより豊かなものにすることができます。このプロセスでは、対話型情報をリアルタイムで端末にプッシュするには、長い接続を使用する必要があります。
ロング接続は、その名前が示すように、アプリケーションの存続期間中サーバーによって維持されるネットワーク データ チャネルであり、全二重のアップリンクおよびダウンリンク データ送信をサポートできます。リクエスト応答モードのショート接続サービスとの最大の違いは、サーバーがリアルタイムでアクティブにユーザーにデータをプッシュできる機能を提供できることです。
この記事では、長時間接続サービスのフレームワーク設計、および安定性と高品質のための関連最適化を含む、Golang に基づいて Bilibili によって実装された数千万の長時間接続リアルタイム メッセージング システムのアーキテクチャ設計と実践を紹介します。スループット。


2. 関連記事
- 「Bilibili のマイクロサービスベース API ゲートウェイの 0 から 1 への進化」
- 「Graphite Document Standalone 500,000 WebSocket 長時間接続アーキテクチャの実践」
- 「百度ユニファイドソケットロング接続コンポーネントの0から1までの技術実践」
- 「Tantan の IM 長時間接続技術の実践: 技術選択、アーキテクチャ設計、パフォーマンスの最適化」
- 「iQiyi WebSocket リアルタイムプッシュゲートウェイ技術実践」
- 「LinkedIn の Web 側インスタント メッセージングの実践: 単一マシンで数十万の長時間接続を実現」
- 「長時間接続をベースにした、安全でスケーラブルなサブスクリプション/プッシュサービスの実装アイデア」
- 「2,500 万接続を誇る Meizu のリアルタイム メッセージ プッシュ アーキテクチャの技術実践の共有」
- 「Meizu Architect 独占インタビュー:大規模な長時間接続を伴うリアルタイム メッセージ プッシュ システムの体験」
3. アーキテクチャ設計
3.1 概要
長時間接続サービスは、複数の取引先で共有する長時間接続です。
なぜなら、設計時には、長期接続サービスに対するさまざまなビジネス当事者の要求やさまざまなビジネスシナリオを考慮する必要があると同時に、ビジネスへの介入を避けるために長期接続サービスの境界も考慮する必要があるからです。ロジックを変更し、その後の長期接続サービスの反復と開発に影響を与えます。
長時間接続サービスは主に次の 3 つの側面に分けられます。
- 1)長距離接続の確立、維持、管理。
- 2)ダウンリンクデータプッシュ。
- 3)アップリンク データ転送 (現在はハートビートのみで、実際のビジネス シナリオ要件はありません)。
3.2 全体的なアーキテクチャ

長時間接続サービスの全体構造を上図に示します。サービス全体には次の部分が含まれます。
1) 制御層:接続確立のための事前呼び出し。主にアクセス合法性検証、身元検証、およびルーティング制御を目的とします。
主な任務:
- 1)ユーザーの身元認証。
- 2)アセンブリデータを暗号化し、合法的なトークンを生成します。
- 3)アクセスノードの動的スケジューリングと割り当て。
2) アクセス層:長時間接続のコア サービス。主に証明書のアンインストール、プロトコル ドッキング、長時間接続の維持を担当します。
主な任務:
- 1)証明書とプロトコルをアンインストールします。
- 2)クライアントとの接続の確立と維持、および接続 ID と roomid 間のマッピング関係の管理を担当します。
- 3)アップリンクおよびダウンリンクのメッセージを処理します。
3) ロジック層:主に長期接続ビジネス機能向けの簡素化されたアクセス層。
主な任務:
- 1)オンライン番号報告記録。
- 2)接続 ID の各属性と各ノード間のマッピング関係を記録します。
- 4)メッセージ配布層:メッセージはアクセス層にプッシュされます。
主な任務:
- 1)メッセージのカプセル化、圧縮、集約が対応するエッジ ノードにプッシュされます。
5) サービス層:ビジネス サービス ドッキング層。ダウンストリーム メッセージ プッシュの入り口を提供します。
主な任務:
- 1)ビジネスプッシュ権限を管理および制御します。
- 2)メッセージの検出と再構築。
- 3)メッセージ フローは、独自のシステムを保護するために特定のポリシーに従って制限されます。
3.3 コアプロセス

長い接続は主に 3 つのコア プロセスで構成されます。
- 1)接続の確立: クライアントによって開始され、最初に制御層を介して、デバイスの正当なトークンとアクセス ポイント構成を取得します。
- 2)接続を維持します。主に、クライアントは定期的にハートビートを開始して、長時間の接続がアクティブであることを確認します。
- 3)ダウンリンク プッシュ: ダウンリンク プッシュはビジネス サーバーによって開始され、サービス層は関連する識別子に従って接続識別子とアクセス ノードを決定し、メッセージ配布層を介して対応するアクセス層にプッシュが送信され、指定されたアドレスに書き込まれます。接続してからクライアントに配布します。
3.4 機能一覧
ステーション B のビジネス シナリオと組み合わせると、ダウンリンク データ プッシュは次の一般的な機能を提供します。
- 1)ユーザーレベルのメッセージ:特定のユーザーにプッシュされるように指定されます (招待 pk メッセージを特定のアンカーに送信するなど)。
- 2)デバイスレベルのメッセージ:開発して特定のデバイスにプッシュします (たとえば、ログが記録されていないデバイスに対するクライアント ログ レポート命令をプッシュします)。
- 3)ルームレベルのメッセージ:特定のルーム内の接続にメッセージをプッシュします (ライブ ブロードキャスト ルーム内のすべてのオンライン ユーザーに集中メッセージをプッシュするなど)。
- 4)パーティション メッセージ:特定のパーティション内のルームにメッセージをプッシュします (たとえば、特定の収益アクティビティを特定のパーティションでブロードキャストされるすべてのルームにプッシュします)。
- 5)地区全体のニュース:すべてのプラットフォーム ユーザーにメッセージをプッシュします (すべてのオンライン ユーザーにイベント通知をプッシュするなど)。
4. 高スループット技術設計
ビジネスの発展と拡大に伴い、オンライン ユーザーがますます増加しており、特に人気のあるイベントのライブ配信など、オンライン ユーザーの数が増加しています。プラットフォーム全体のメッセージ スループットは数億に達し、Changlian システムのメッセージ配信の平均遅延は約 1 秒で、メッセージ到着率は 99% に達しました。長連がとった措置。
4.1 ネットワークプロトコル
適切なネットワーク プロトコルを選択することは、長時間接続システムのパフォーマンスにとって重要です。
- 1) TCP プロトコル: 信頼性の高い接続とデータ送信を提供でき、高いデータ信頼性が必要なシナリオに適しています。
- 2) UDP プロトコル: 信頼性は低いプロトコルですが、伝送効率が高く、データの信頼性をそれほど必要としないシナリオに適しています。
- 3) WebSocket プロトコル: オーバーヘッドをあまり追加せずに双方向通信を実現するため、Web 側で多く使用されます。
アクセス層は、プロトコル モジュールと接続モジュールに分割されます。
- 1)プロトコル モジュール: 特定の通信層プロトコルと対話し、さまざまな通信プロトコルのインターフェイスと論理的な違いをカプセル化します。
- 2)接続モジュール: 長期接続ビジネス接続のステータスを維持し、アップリンク、ダウンリンク、その他のビジネス ロジックの要求をサポートし、接続の属性とルーム ID とのバインディング関係を維持します。
上記のポイント1)に関して 、プロトコル モジュールは、接続の確立、データの読み取り、書き込みなどを含む、接続モジュールへの統合データ インターフェイスも提供します。将来新しいプロトコルが追加された場合でも、プロトコル モジュール内で適応が行われている限り、他のモジュールの長期的なビジネス ロジックには影響しません。
の利点:
- 1)ビジネス ロジックと通信プロトコルが分離されているため、通信プロトコルの反復追加が容易になり、複数の通信プロトコルとの互換性による実装の困難さが簡素化されます。
- 2)制御層は、クライアントの実際の状況に基づいて、より適切な通信プロトコルを発行できます。
4.2 負荷分散
負荷分散テクノロジーを使用すると、リクエストをさまざまなサーバー ノードに分散して処理することができ、単一ノードへの過剰な負荷を回避し、システムのスケーラビリティと安定性を向上させることができます。
長期接続では、負荷分散のための制御層が追加されます。制御層は http ショート接続インターフェイスを提供し、クライアントと各エッジ ノードの実際の状況と近接性の原則に基づいて適切なアクセス ノードを動的に選択します。
アクセス層は水平拡張をサポートし、制御層は割り当てノードをリアルタイムで追加および削減できます。 S ゲーム中、オンライン人口が数千万人に近づいたとき、各アクセス ノードのバランスがとられ、各ノードの CPU とメモリが安定した範囲内に収まるようにスケジュールされました。
4.3 メッセージキュー
メッセージ プッシュ リンクは次のとおりです。企業はプッシュを送信し、サービス層を介してエッジ ノードにプッシュし、クライアントに配信します。
サービス層は各エッジノードにリアルタイムで配信します。ルームタイプのメッセージの場合、サービス層はビジネスロジックも処理する必要があり、メッセージのスループットに大きく影響します。
したがって、メッセージ キューとメッセージ配布層が追加され、各エッジ ノードの情報を保持してメッセージをプッシュすることで、システムの同時処理能力と安定性が向上し、メッセージ プッシュのブロックによって引き起こされるパフォーマンスの問題が回避されます。
4.4 メッセージの集約
人気のあるイベントの場合、同時にオンラインに参加する人が数千万人に達することもあり、オンラインにいる全員が毎秒 1 つのメッセージを送信すると、集中メッセージが数千万台の端末に拡散されます。送信する必要があるメッセージは 1kw*1kw で、これは非常に大量のメッセージです。このとき、メッセージ配信層とアクセス層には大きな負荷がかかります。
分析の結果、これらのメッセージはすべて同じルームからのものであり、S ゲーム ルームなどのホット ルームに属していることがわかりました。視聴者数を減らすことはできないため、メッセージの数について大騒ぎすることしかできません。ビジネスメッセージのプッシュは減らすことができず、拡散されるメッセージの数も減らす必要があるため、メッセージの集約が考えられました。
ルーム メッセージの場合、メッセージの集約は特定のルールに従って実行され、バッチでプッシュされます。

メッセージ アグリゲーションがオンラインになると、メッセージ配布層によってアクセス層に呼び出される QPS が約 60% 削減され、アクセス層とメッセージ配布層への負担が大幅に軽減されます。
4.5 圧縮アルゴリズム
メッセージの集約後、メッセージの数は減りますが、メッセージ本文のサイズは増加するため、書き込み IO に影響します。メッセージ本文のサイズを削減する必要がある場合は、メッセージの圧縮を検討してください。
圧縮アルゴリズムについては、比較のために、市場で一般的に使用されている 2 つのアルゴリズム、zlib と brotli を選択しました。
オンライン ビジネスによってプッシュされたデータをキャプチャし、最も高い圧縮レベルを選択し、圧縮検証に合格しました。

brotli には zlib よりも大きな利点があることがわかり、最終的に brotli 圧縮アルゴリズムが選択されました。
各アクセス ノードでの繰り返しの圧縮とパフォーマンスの無駄を避けるために、メッセージ配布層でメッセージ圧縮を実行することを選択します。オンラインになると、スループットが向上するだけでなく、ブロードバンドの使用コストも削減されます。
5. サービス保証技術設計
現在、一部の企業は長期にわたるプッシュ メッセージに大きく依存しており、メッセージが失われると、良くてもユーザー エクスペリエンスに影響があり、最悪の場合はその後のビジネス プロセスがブロックされ、ビジネス フローに影響を及ぼします。サービスメッセージの長期保証を保証するために、次の作業が行われました。
5.1 マルチアクティブ展開
マルチアクティブ展開では、地理的に異なる場所に同じシステム アーキテクチャとサービスを展開することで、単一の地理的障害が発生した場合にシステムの迅速なフェイルオーバーが実現され、システムの安定性と可用性が向上します。

長期的なサービス展開には主に次の点が含まれます。
- 1) LongConnect は中国東部、中国南部、中国北部にアクセス ポイントを展開し、3 つの大手通信事業者をサポートしています。また、海外ユーザーと独立したアクセスをサポートするために、中国南部と中部の自社製コンピューター ルームにもアクセス ポイントを展開しています。シンガポールのコンピュータルームにポイントが追加されました。
- 2)さまざまなビジネス シナリオに合わせて、クラウド ノードと自社構築ノードをリアルタイムに切り替えます。クラウド ノードと自社構築のコンピュータ ルームのコストは異なるため、サービスの品質を確保しながらコストを可能な限り制御する必要があります。
現在のオンライン運用中に、単一ノードまたはコンピューター室のネットワークジッターが発生することがありますが、制御層を通じて問題のあるノードが数秒で削除され、ビジネスへの影響が大幅に軽減されます。
5.2 高および低メッセージ チャネル
マルチサービス メッセージは長い接続にアクセスしますが、集中砲火メッセージや招待 pk メッセージなど、メッセージの重要性は異なります。いくつかの集中砲火メッセージが失われても、ユーザー エクスペリエンスに大きな影響はありませんが、招待 pk メッセージが失われた場合でも同様です。 、pk業務がその後の処理を進めることができなくなります。
さまざまなレベルのメッセージに対して、高品質、低品質のメッセージ チャネルが使用されます。重要なニュースは高品質のチャンネルに送られ、一般的なニュースは低品質のチャンネルに送られます。このように、重要なメッセージと通常のメッセージを物理的に分離し、重要なメッセージを優先してメッセージを配信します。

高品質チャネルの場合、二重配信が保証され、冪等重複排除がアクセス層で実行されます。まず、重要なメッセージはユーザーレベルのものであり、その量はそれほど大きくないため、アクセス層への負担はそれほど大きくなりません。さらに、二重配信ジョブは複数のコンピューター ルームに展開されるため、単一のコンピューター ルームでのネットワーク ジッターの影響が軽減されます。
高品質チャネルと低品質チャネルがオンラインになった後、イントラネットの送信ジッターが発生しました。そのとき、イントラネットに属するジョブ ノードは異常にメッセージをプッシュしましたが、クラウド上の高品質ジョブ ノードは正常にメッセージをプッシュできました。高品質のメッセージが確実に到着するため、高品質のサービスが影響を受けないことが保証されます。
5.3 ガンダムの機能
高低最適化チャネルはジョブからアクセス層へのリンクを解決しますが、メッセージ プッシュ接続にはサービス層からジョブ、アクセス層からクライアントなどの複数のリンクが関係します。
リンク全体では、リーチ機能と呼ばれるマストリーチ機構を実装することで端末の到着速度が確保されます。

関数の実装:
- 1)各メッセージには msgID が導入され、クライアントはメッセージの受信後に冪等重複排除と受信確認を実行します。
- 2)サーバーは msgid に対して ack 検出を実行し、ack がない場合、サーバーは有効期間内に配信を再試行します。
最終到着レート = (1-(1-r)^(n+1))、ここで: r はブロードキャストの 1 回の到着レート、n は最大再試行数です。
例: r = 97%、n=2 の場合、最終到着率は (1-(1-0.97)^(2+1)) = 99.9973% に達します。
6. 「ルーム」に出入りするメッセージの到達保証設計
一部のビジネス シナリオでは、ユーザーの入退室情報を使用する必要があります。たとえば、ユーザー A がライブ ブロードキャスト ルームに入ると、ページにはユーザー A の入室またはオンライン リストへの参加を歓迎するメッセージが表示されます。
1)入室情報が失われるため、補償の仕組みが必要。入室メッセージはハートビートに接続することで補えるのではないかと考えましたが、オンライン接続中はハートビートが継続しているため、ビジネス側は入室メッセージを一度だけ受信したいため、入室メッセージには冪等性が必要です。機構。
2)ルームのチェックアウト情報も失われます。紛失した場合、企業はオンライン リストからユーザーを削除することはできません。この際、補償の仕組みも必要です。この時点で、接続のステート マシンを追加し、ハートビートを通じてステート マシンを維持する必要があります。ハートビートが失われると、接続は切断されたとみなされ、ユーザーはチェックアウトします。

7. 今後の計画
統合された長時間接続サービスは数回の反復を経て、基本機能が安定しており、将来的には長時間接続サービスの改善と最適化が行われます。
主に次の方向に焦点を当てます。
- 1)データ化: 長距離接続のフルリンク ネットワーク品質データ統計と高価値メッセージのフルリンク追跡を収集する機能をさらに向上させます。
- 2)インテリジェント化: デバイス上の接続確立、アクセス ポイントの選択などを実際の環境に応じて自動的に調整できます。
- 3)パフォーマンスの最適化: アクセス層の接続モジュールでは、アップリンクおよびダウンリンクのメッセージを処理する Ctrip が共有され、アクセス層の Ctrip の数が削減され、単一マシンのパフォーマンスと接続数がさらに向上します。
- 4)機能拡張:オフラインメッセージ機能などを追加しました。
8. 参考資料
[1] TCP に基づいて長いソケット接続を作成する方法を段階的に説明します。
[2] IM の長時間接続、ハートビート、再接続のメカニズムを正しく理解し、実践的に実装する
[3] 10,000 ワードの長文: 効率的な IM 長時間接続の適応型ハートビート キープアライブ メカニズムを実装する方法を段階的に説明します。
[4] JWT技術を利用してIMシステムの本人認証の問題点を解決 ソケットロング接続
[5] TCP/IPの詳しい解説 - 第11章・UDP: ユーザーデータグラムプロトコル
[6] TCP/IPの詳しい解説 - 第17章・TCP: 伝送制御プロトコル
[7] WebSocket の初心者から熟練者まで、30 分で十分です。
[8] TCP プロトコルをすぐに理解するには 1 つの記事で十分です
[10] 一回のおしっこで、TCPとUDPの違いがすぐに理解できる
[11] ソケットとは何ですか? 1記事でわかる!
[12] Socket を読み書きするとき、具体的には何を読み書きするのでしょうか?
[13] あなたが TCP プロトコルを設計するとしたら、何をしますか?
[14] オペレーティング システムを深く掘り下げ、1 つの記事でソケットとは何かを理解する
[15] 高性能サーバーがどのように実装されているかを理解するのは簡単です。
[16] 12306 チケット取得によってもたらされた啓発: Go を使用して 100 万 QPS フラッシュ セール システムを実装する方法をご覧ください (ソース コードを含む)
- モバイルIM開発の入門記事「初心者はこの記事1つで十分!ゼロからモバイルIMを開発する」
- オープンソース IM フレームワークのソース コード: https://github.com/JackJiang2011/MobileIMSDK (代替アドレスはここをクリック)
(この記事はhttp://www.52im.net/thread-4647-1-1.htmlで同時公開されています)