ユニットあたり 120 万の接続がある Xiaoai ゲートウェイはどのように構成されていますか?

目の前で言った

40 歳の建築家、ニエン氏の読者交換グループ(50 歳以上)では、多くの友人がアリババ、ネットイース、ヨウザン、Xiyin、Baidu、Didi などの一流インターネット企業の面接資格を取得しています。

最近、ニエンは友人の履歴書を案内し、「長時間接続ゲートウェイ プロジェクトのアーキテクチャと実際の運用」を書きました。このプロジェクトのおかげで、この男はByte/Alibaba/Weibo/Autohome から面接の招待状を得ることができました。つまり、これは素晴らしいプロジェクトです。

より多くの面接機会を獲得し、大手企業からより多くの内定を得るために、

Nien は、このプロジェクトのアーキテクチャと実際の操作を紹介するビデオの章「第 33 章: 10Wqps の高同時実行 Netty ゲートウェイのアーキテクチャと実際の操作」を 9 月に公開することを決定し、今月末にリリースされる予定です。そして、マンツーマンで履歴書指導を行い、あなたの履歴書を輝かせ、完全に変えます。

「第 33 章: 10Wqps の高同時実行 Netty ゲートウェイのアーキテクチャと実際の運用」 ポスターは次のとおりです。

「第 33 章: 10Wqps の高同時実行 Netty ゲートウェイのアーキテクチャと実際の運用」と併せて、Nien はアーキテクチャおよび設計資料として、いくつかの産業グレードおよびプロダクション グレードのゲートウェイ ケースを整理します。

前に整理しました

上記の 5 つのケースに加えて、学習ケースを整理する過程で、ニエン氏はもう 1 つの美しい運用レベルのケースを見つけました。「単一ユニットに 120 万の接続がある場合、Xiaoai ゲートウェイはどのように構成されているのでしょうか?」》、

注意してください、これはもう 1 つの非常に素晴らしい、一流の産業グレードおよび生産グレードのゲートウェイ ケースです。

これらのケースは Nien 独自のものではありません。

これらの事例は、誰もが学び、コミュニケーションできるビデオ レッスン「第 33 章: 10Wqps の高同時実行性 Netty ゲートウェイ アーキテクチャと実際の操作」の準備中に、インターネットで情報を検索し、Nien が収集したものです。

『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』の PDF は、公式アカウント [Technical Freedom Circle] から入手してください。

ユニットあたり 120 万の接続がある Xiaoai ゲートウェイはどのように構成されていますか?

著者: Xiaoai 技術チーム

1. Xiaoaiアクセスゲートウェイの大きな進化の成果

Xiao Ai (「Xiao Ai Classmate」としても知られる) は、Xiaomi が所有する人工知能音声インタラクション エンジンです。

「Xiaoai Classmate」は、Xiaomi グループの統合インテリジェント音声サービス インフラストラクチャです。

「Xiao Ai Classmate」クライアントは、Xiaomi 携帯電話、Xiaomi AI スピーカー、Xiaomi TV、その他のデバイスに統合されており、パーソナル モビリティ、スマート ホーム、スマート ウェアラブル、スマート オフィス、子供向けエンターテイメント、スマート トラベル、スマート ホテルなどで広く使用されています。スマートラーニングなど8つのシーン。

Xiaoai アクセス レイヤーは、Xiaoai クラウド デバイス アクセスの主要なサービスであり、コア サービスの 1 つです。

Xiaomi 技術チームは、2020 年から 2021 年にかけて、このサービスに関して一連の最適化と試みを実施しました。最終的には、1 台のマシンが伝送できる長い接続の数を 300,000 から 120W 以上に増やすことに成功し、30 台以上のマシンを節約しました。

2.Xiaoai アクセス レイヤーとは何ですか?

Xiaoai の全体的なアーキテクチャの層は次のとおりです

アクセス サービスは主に認証および認可層とトランスポート層を担当し、すべての Xiaoai デバイスが Xiaoai Brain と対話する最初のサービスです。

上の図から、Xiaoai アクセス サービスの重要な機能には次の点が含まれていることがわかります

  • 1) 安全な送信と認証: デバイスと脳の間の安全なチャネルを保護し、ID 認証の有効性とデータ送信のセキュリティを確保します。
  • 2) 長い接続を維持する: デバイスと脳の間の長い接続 (Websocket など) を維持し、接続状態を適切に保存し、ハートビートのメンテナンスやその他のタスクを実行します。
  • 3) リクエストの転送: Xiaoai デバイスからの各リクエストを転送して、各リクエストの安定性を確保します。

3. 早期アクセス層の技術的実装

Xiaoai アクセス レイヤーの初期の実装はAkkaplayframeworkに基づいていました。最初のバージョンの構築にはそれらを使用しました。その機能は次のとおりです。

  • 1) Akka に基づいて、コアスレッドがブロックされず、パフォーマンスが良好になるように予備的な非同期を実装しました。
  • 2) Playframework フレームワークは当然 Websocket をサポートしているため、限られたマンパワーで迅速に構築および実装でき、プロトコル実装の標準化を確実に行うことができます。

play と呼ばれる playframework は、springmvc に似た Web 開発フレームワークであることに注意してください。

4. 早期アクセス層の技術的問題

XiaoAi の長時間接続の数が数千万に達したとき、早期アクセス層のソリューションにいくつかの問題があることがわかりました。

主な問題は次のとおりです

  • 1) 長い接続の数が増加するにつれて、より多くのメモリ データを維持する必要があり、JVM の GC がパフォーマンスのボトルネックになり、GC のリスクが生じます。インシデント分析の結果、Akka+Play バージョンのアクセス層における単一インスタンスのロング接続数の上限は約 280,000 であることが判明しました。
  • 2) 古いバージョンのアクセス層の実装は比較的ランダムです。Akka アクター間には多くの状態依存関係があり、不変のメッセージ パッシングに基づいていません。その結果、アクター間の通信は関数呼び出しのようなものになります。コードは読みにくく、保守が難しく、機能しません。並行プログラムの構築における Akka Actor の利点。
  • 3) アクセス層サービスとして、古いバージョンはプロトコル解析に強く依存しており、バージョン更新で頻繁にオンラインにする必要があるため、接続の再接続に時間がかかり、雪崩のリスクが生じる可能性があります。
  • 4) Play フレームワークに依存しているため、その長時間接続の管理が不正確であることがわかりました (基盤となる TCP 接続データが取得できないため)。これは、サービス容量評価の毎日の検査と長時間接続の数の後に影響を与える可能性があります。増加すると、より詳細な最適化を実行できなくなります。

5. 新しいアクセス層の設計目標

初期アクセス層の技術的解決策には多くの問題があることを考慮して、アクセス層を再構築することにしました。

新しいバージョンのアクセス層の設計目標は次のとおりです

  • 1) 高い安定性: 安定したサービスを確保するために、オンラインプロセス中の切断を可能な限り回避します。
  • 2) 高性能: ターゲットの単一マシンは少なくとも 100 万の長い接続を実行でき、GC の影響を回避しようとします。
  • 3) 高い制御性: 基盤となるネットワーク I/O のシステム コールを除き、他のすべてのコードは独自に実装するか、自律性を高めるために内部コンポーネントを使用する必要があります。

したがって、私たちは 1 台のマシンで数百万もの長時間接続を実現するための探求の旅に乗り出しました。

6. 新しいアクセス層の最適化アイデア

6.1 アクセス層の依存関係

アクセス層と外部サービスの関係は次のように明確になります

6.2 アクセス層の機能分割

アクセス層の主な役割は次のように要約できます

  • 1) WebSocket デコード: 受信したクライアント データ ストリームは、WebSocket プロトコルに従って解析する必要があります。
  • 2) ソケット状態の維持: 接続の基本情報を保存します。
  • 3) 暗号化と復号化: クライアントと通信されるすべてのデータは暗号化される必要があり、バックエンド モジュール間の送信はプレーン テキストの JSON です。
  • 4) シーケンシャル化: 同じ物理接続上の 2 つのリクエスト A と B がサーバーに到着します。バックエンド サービスでは、B が A より先にレスポンスを取得する可能性がありますが、A が完了するまで待機してからクライアントにリクエストを送信する必要があります。 A と B の順序。
  • 5) バックエンド メッセージの配布: アクセス層は、単一​​のサービスとインターフェイスするだけでなく、さまざまなメッセージに基づいてさまざまなサービスにリクエストを転送することもあります。
  • 6) 認証:セキュリティ関連の検証、本人確認など。

6.3 アクセス層の分割の考え方

ステータスがあるかどうかに応じて、前の単一モジュールを 2 つのサブモジュールに分割します。

詳細は以下のとおりです

  • 1) フロントエンド: ステートフル、最小化された機能、および最小化されたオンライン。
  • 2) バックエンド: ステートレス、最大化された機能、オンライン時にユーザーを認識しません。

したがって、上記の原則に従って、理論的には、フロントエンドがより小さく、バックエンドがより大きいというような機能分割を達成することになります。概略図を以下に示します。

7. 新しいアクセス層の技術的実装

7.1 概要

モジュールはフロントエンドとバックエンドに分割されています

  • 1) フロントエンドはステートフルで、バックエンドはステートレスです。
  • 2) フロントエンドとバックエンドは独立したプロセスですが、同じマシン上にデプロイされます。

補足:フロントエンドはデバイスの長時間接続の状態を維持する役割を担うためステートフルなサービスであり、バックエンドは特定のビジネスリクエストの処理を担うためステートレスなサービスです。バックエンドサービスの起動により、デバイスの接続が中断され再接続されたり、認証呼び出しがトリガーされたりすることはなく、バージョンアップグレードやロジック調整による長時間にわたる接続状態の不要な変動を回避します。

フロントエンドは C++ で実装されています

  • 1) WebSocket プロトコルを独立して解析します。ソケット レベルからすべての情報を取得し、バグを処理できます。
  • 2) CPU 使用率の向上: 追加の JVM オーバーヘッドがなく、GC によるパフォーマンスの低下もありません。
  • 3) メモリ使用量の増加: 接続数が増加すると、接続に関連するメモリ消費も増加し、自己管理により極端な最適化を達成できます。

バックエンドは一時的に Scala に実装されます

  • 1) 実装された関数は、書き換えよりもはるかに低いコストで直接移行できます。
  • 2) 一部の外部サービス (認証など) には、直接使用できる Scala (Java) SDK ライブラリがありますが、C++ 版はなく、C++ で書き直すとコストが非常に高くなります。
  • 3) すべての関数はステートレス関数に変換され、ユーザーが気付かないでいつでも再起動できます。

通信はZeroMQを使用します。

  • プロセス間の通信に最も効率的なのは共有メモリであり、ZeroMQは共有メモリをベースに実装されているため、速度に問題はありません。

7.2 フロントエンドの実装

全体的なアーキテクチャ:

上の図に示すように、これは 4 つのサブモジュールで構成されています

  • 1) トランスポート層: Websocket プロトコル分析、XMD プロトコル分析。
  • 2) ディストリビューション層: トランスポート層の差異を保護し、トランスポート層がどのようなインターフェイスを使用しても、ディストリビューション層で統一されたイベントに変換され、ステート マシンに配信されます。
  • 3) ステート マシン層: 純粋な非同期サービスを実装するために、アクター モデルに基づいて独自に開発された Akka のようなステート マシン フレームワーク XMFSM が使用されます。これは、シングルスレッドのアクター抽象化を実装します。
  • 4) ZeroMQ 通信層: ZeroMQ インターフェイスはブロッキング実装であるため、この層は 2 つのスレッドを介した送受信を担当します。

7.2.1 トランスポート層:

WebSocket 部分は C++ と ASIO を使用して websocket-lib を実装します。Xiaoai ロング接続は WebSocket プロトコルに基づいているため、WebSocket ロング接続ライブラリを独自に実装しました。

この長い接続ライブラリの特徴は次のとおりです

  • a.優れたパフォーマンスを保証するロックフリー設計。
  • b.基本的なネットワーク パフォーマンスを確保するために、BOOST ASIO に基づいて開発されています。

ストレス テストでは、このライブラリのパフォーマンスが非常に優れていることが示されています

ロングリンクの数 SWC P99遅延
100ワット 5w 5ミリ秒

この層は、元の WebSocket に加えて、他の 2 つのチャネルの送受信タスクも担当します。

現在、トランスポート層は次の 3 つの異なるクライアント インターフェイスをサポートしています

  • a. websocket (tcp): ws と呼ばれます。
  • b. SSL ベースの暗号化 WebSocket (tcp): wss と呼ばれます。
  • c. xmd(udp): xmd と呼ばれます。

7.2.2 ディストリビューション層:

さまざまなトランスポート層イベントを統合イベントに変換し、それらをステート マシンに配信します。この層は、前のトランスポート層でどのタイプが使用されているかに関係なく、ディストリビューション層に到達すると、一貫したイベントになるようにするアダプターとして機能します。そしてステートマシンに渡されます。

7.2.3 ステートマシン処理層:

主要な処理ロジックはこの層にあり、ここでの非常に重要な部分は送信チャネルのカプセル化です。

Xiaoai アプリケーション層プロトコルの場合、さまざまなチャネルの処理ロジックは完全に一貫していますが、各チャネルの処理とセキュリティ関連のロジックには詳細な違いがあります。

たとえば:

  • a. WSS の送受信には暗号化と復号化は必要ありません。暗号化と復号化はフロントエンドの Nginx によって実行されますが、WSS は AES 暗号化を使用して送信する必要があります。
  • b.認証が成功した後、wss は暗号化と復号化を実行する必要がないため、クライアントにチャレンジ テキストを送信する必要はありません。
  • c. xmd が送信する内容は他の 2 つとは異なり、protobuf によってカプセル化されたプライベート プロトコルに基づいており、xmd は送信失敗後のロジックを処理する必要がありますが、ws/wss は送信失敗の問題を考慮する必要がありません。 、これは基礎となる Tcp プロトコルによって保証されています。

この状況に対応して、C++ の多態性機能を使用してそれに対処し、特にチャネル インターフェイスを抽象化します。このインターフェイスで提供されるメソッドには、リクエスト処理のいくつかの重要なステップ、クライアントへのメッセージの送信方法、接続を停止する方法、送信できない場合の対処方法など。3 つの異なる送信チャネル (ws/wss/xmd) の場合、各チャネルには独自のチャネル実装があります。

クライアント接続オブジェクトが作成されるとすぐに、対応するタイプの特定の Channel オブジェクトがインスタンス化されます。このように、ステート マシンのメイン ロジックは、ビジネス層の共通ロジックを実装するだけで済みます。差分ロジックの呼び出しがある場合は、チャネル インターフェイスが直接呼び出されて完了します。このような単純なポリモーフィックな機能により、差異を分離することができます。コードがクリーンであることを確認してください。

7.2.4 ZeroMQ 通信層:

ZeroMQ の読み取りおよび書き込み操作は 2 つのスレッドを通じて非同期であり、いくつかのプライベート命令のカプセル化と解析を担当します。

7.3 バックエンドの実装

7.3.1 ステートレス変換:

バックエンドに加えられた最も重要な変更の 1 つは、接続ステータスに関連するすべての情報を削除することです。

サービス全体では、リクエスト (1 つの接続で N 個のリクエストを送信できます) を中心としてさまざまな転送や処理が行われ、各リクエストは前のリクエストとは関係がありません。1 つの接続上の複数のリクエストは、バックエンド モジュールによって独立したリクエストとして扱われます。

7.3.2 アーキテクチャ:

Scala サービスは、Akka-Actor アーキテクチャを使用してビジネス ロジックを実装します。

サービスが ZeroMQ からメッセージを受信すると、データ分析とリクエスト処理のためにディスパッチャーに直接配信され、ディスパッチャー内のさまざまなリクエストがイベント プロトコル分析のために対応する RequestActor に送信され、イベントに対応するビジネス アクターに配信されます。処理。最後に、処理されたリクエスト データは、XmqActor を通じてバックエンド AIMS&XMQ サービスに送信されます。

バックエンドの複数のアクターにおけるリクエストの処理フロー:

7.3.3 ディスパッチャーは配布を要求します。

Protobuf を使用すると、フロントエンドとバックエンドが対話できるため、Json 解析のパフォーマンスが節約され、プロトコルがより標準化されます。

ZeroMQ によって送信されたメッセージを受信した後、バックエンド サービスは DispatcherActor で PB プロトコルを解析し、さまざまな分類 (略して CMD) に従ってデータを処理します。

バインドコマンド:

この関数はデバイス認証に使用されますが、認証ロジックは複雑で C++ での実装が難しいため、認証は依然として scala ビジネス層で実行されます。この部分は主に、デバイスによって要求された HTTP ヘッダーを解析し、認証用のトークンを抽出し、その結果をフロントエンドに返します。

ログインコマンド:

このコマンドはデバイスへのログインに使用されます。デバイスが認証に合格し、接続が正常に確立されると、LOGIN コマンドを実行して長い接続情報を AIMS に送信し、後続のアクティブ プッシュやその他の機能のために Varys サービスに記録します。LOGIN プロセス中、サービスはまずアカウント サービスに長い接続の uuid (接続プロセス中のルーティング アドレス指定に使用される) を取得するよう要求し、次にデバイスのログイン操作のためにデバイス情報 + uuid を AIMS に送信します。

ログアウトコマンド:

このコマンドはデバイスからログアウトするために使用されます。デバイスがサーバーから切断されると、ログアウト操作を実行して、Varys サービスから長い接続レコードを削除する必要があります。

UPDATE および PING コマンド:

  • a.更新コマンド (デバイス状態情報更新) は、デバイスのデータベースに保存されている関連情報を更新するために使用されます。
  • b. Ping コマンド、接続キープアライブを使用して、デバイスがオンラインであることを確認します。

TEXT_MESSAGE と BINARY_MESSAGE

テキスト メッセージとバイナリ メッセージ: テキスト メッセージまたはバイナリ メッセージを受信すると、リクエストに対応する RequestActor に送信され、requestid に従って処理されます。

7.3.4 リクエストリクエストの分析:

受信したテキストおよびバイナリ メッセージは、DispatcherActor によって対応する RequestActor に送信され、requestId に従って処理されます。

その中で、テキスト メッセージはイベント リクエストに解析され、名前空間と名前に基づいて指定されたビジネス アクターに配布されます。バイナリ メッセージは、現在要求されているビジネス シナリオに従って、対応するビジネス アクターに配布されます。

7.4 その他の最適化

新しいアーキテクチャ 1.0 の調整を完了する過程で、私たちは接続容量を常に測定し、容量に大きな影響を与えるいくつかのポイントをまとめています。

7.4.1 プロトコルの最適化:

  • a. JSON を Protobuf に置き換える: 初期のフロントエンドとバックエンドの通信では JSON テキスト プロトコルが使用されていましたが、JSON のシリアル化と逆シリアル化に多くの CPU が使用されることが判明しました。Protobuf プロトコルに切り替えた後、CPU 使用率は低下しました。大幅。
  • b. JSON は部分解析をサポート: ビジネス層プロトコルは JSON に基づいており、直接置き換えることができないため、小さなヘッダー部分のみを解析して名前空間と名前を取得し、大部分を転送する「部分解析 JSON」の方法を採用します。直接転送されたメッセージのうち、オブジェクトに完全に逆シリアル化されるのは、少量の JSON メッセージだけです。この最適化後、CPU 使用率は 10% 削減されます。

7.4.2 ハートビート時間を延長する:

最初に 20w 接続をテストしたとき、フロント エンドとバック エンドで送受信されるメッセージのうち、ユーザーをオンラインに保つために使用されるハートビート PING メッセージがメッセージ総量の 75% を占めていることがわかりました。たくさんのCPU。したがって、ハートビート時間を延長し、CPU 消費量を削減するという目的も達成します。

7.4.3 自社開発のイントラネット通信ライブラリ:

バックエンドサービスとの通信性能を向上させるため、Boost ASIOをベースに開発した純粋非同期マルチスレッドTCPネットワークライブラリである自社開発TCP通信ライブラリを使用しており、その優れた性能により通信数の増加に貢献しています。 120w+までの接続数。

8. 今後の計画

新しいアーキテクチャのバージョン 1.0 の最適化後、事前に設定された目標が達成されたため、分割方向が正しいことが検証されました

  • 1) 単一マシンで伝送される接続数は 28w => 120w+ (16G メモリと 40 コアを搭載した通常のサーバー マシンのピーク リクエスト QPS は 10,000 を超えます)、アクセス レイヤがオフラインになり、マシン コストが 50% 以上節約されます。 ;
  • 2) バックエンドはロスレスで起動できます。

理想の目標を再検討しましょう。これを方向性として、バージョン 2.0 のプロトタイプが完成しました

具体的には:

  • 1) バックエンド モジュールは C++ で書き直され、パフォーマンスと安定性がさらに向上しました。同時に、バックエンドモジュールのC++で書き換えることができない部分は、独立したサービスモジュールとして運用・保守され、ネットワークライブラリを介してバックエンドモジュールが呼び出されます。
  • 2) フロントエンドの機能を減らし、より安定させるために、フロントエンド モジュール内の必須ではない機能をバックエンドに移行してみます。
  • 3) 変換後、フロントエンドとバックエンドの処理能力が大きく異なる場合、ZeroMQ が実際に過剰なパフォーマンスを持っていることを考慮すると、ZeroMQ をネットワーク ライブラリで置き換えることを検討できます。バックエンドは、1:1 の単一マシンから 1:N のマルチマシンへの展開が可能で、マシンのリソースを有効に活用できます。

バージョン 2.0 の目標は次のとおりです。上記の変換後、単一のフロントエンド モジュールが 200 万以上の接続処理能力に到達できることが期待されます。

最後に: 質問がある場合は、古いアーキテクチャにアドバイスを求めることができます。

建築の道は山あり谷あり

アーキテクチャは高度な開発とは異なります。アーキテクチャに関する質問はオープン/オープンであり、アーキテクチャに関する質問に対する標準的な回答はありません。

このため、多くの友人は多大なエネルギーとお金を費やしたにも関わらず、残念ながら一生のうちにアーキテクチャのアップグレードを完了することができません

したがって、アーキテクチャのアップグレード/変革のプロセスにおいて、どうしても効果的な解決策が見つからない場合は、40 歳の建築家 Nien に助けを求めることができます。

少し前に、専攻を超えて Java に取り組んでいた友人がいて、現在、アーキテクチャの切り替えの問題に直面していますが、Nien からの数回の指導の後、無事 Java アーキテクト + ビッグデータ アーキテクトの内定を獲得しまししたがって、キャリア上で困難に直面した場合は、経験豊富な建築家に助けを求める方がスムーズです。

推奨読書

100 億回の訪問、キャッシュ アーキテクチャの設計方法

多層キャッシュアーキテクチャ設計

メッセージプッシュアーキテクチャ設計

Alibaba 2: ノードは何台導入していますか?」1000W の同時実行を導入するにはどうすればよいですか?

Meituan 2 Sides: Five Nines 高可用性 99.999%。それを達成するにはどうすればよいですか?」

NetEase 側: シングルノード 2000Wtps、Kafka はどうやってそれを行うのですか?」

バイト側: トランザクション補償とトランザクション再試行の関係は何ですか?」

NetEase 側: Mysql 書き込み 25Wqps の高スループット、100W データは 4 秒で書き込まれます。これを達成するにはどうすればよいですか?」

10億レベルのショートビデオをどのように構成するか? 」

爆上げ、「自慢」に頼ってJD.comを乗り切る、月給4万

あまりに過酷なので、『自慢』に頼ってSFエクスプレスを乗り切り、月収は3万です

爆発しました...Jingdongは片側で40の質問を要求し、それを通過した後、それは500,000以上でした

質問するのはもううんざりです...アリは命を懸けて27の質問をしました、そしてそれを通過した後の質問は60万以上です

Baidu で 3 時間質問し続けた結果、大手企業からオファーをもらいました。この男は本当に残酷です!」

Ele.me は残酷すぎる: 高度な Java に直面して、それがどれほど困難で残酷な作業であるか

Byteに1時間尋ねた後、その男はオファーを受け取りました。それはとても残酷です!」

Didi のオファーを受け入れます: 若い頃の 3 つの経験から、何を学ぶ必要があるかわかりますか?」

『Nien Architecture Notes』、『Nien High Concurrency Trilogy』、『Nien Java Interview Guide』PDF は、下記公式アカウント【Technical Freedom Circle】から入手してください ↓↓↓

おすすめ

転載: blog.csdn.net/crazymakercircle/article/details/132941352