以前、「*** のメッセージ プッシュ システムの設計」という記事を共有しました。記事にはいくつかの疑似コードが掲載されていますが、実行可能なソースコードを直接共有したいと考えている友人もいます。長い間経ちましたので、その穴を埋める時が来ました。 そこで、以前の内容に基づいていくつかの内容を改善しました。このプロジェクトの紹介を見てみましょう。CIM (CROSS-IM) は開発者向けの IM (インスタント メッセージング) システムです。また、開発者が独自の水平スケーラブルな IM を構築するのに役立つコンポーネントもいくつか提供します。 CIM を使用すると、次の要件を実現できます。
完全なソースコードは GitHub でホストされています:
今回は主に IM インスタント メッセージングに関するものなので、特別に 2 つのビデオ デモ (グループ チャットとプライベート チャット) を録画しました。 グループチャット
プライベートチャット 建築デザイン 具体的なアーキテクチャ設計を見てみましょう。
システム全体は主に以下のモジュールで構成されています。
フローチャート 全体的なプロセスは比較的単純で、フローチャートは次のとおりです。
したがって、自分でデプロイする場合は、次の手順に従う必要があります。
詳しい使用方法については、クイックスタートを参照してください。 詳細設計 次に、グループチャットやプライベートチャットのメッセージの流れなど、具体的な実装に焦点を当てます。 IM サーバーの負荷分散。サービスが登録および検出される方法など。 IM サーバー まずサーバーを見てみましょう。主にクライアントのオンラインとオフライン、メッセージ送信などの機能を実装します。 まず、サービスを開始します。 Spring Boot で構築されているため、アプリケーションの起動時に Netty サービスを開始する必要があります。 Pipline からは、Protobuf エンコードとデコードが使用されていることがわかります (特定のメッセージがクライアントで分析されます)。 登録の検出 IM サーバーの水平拡張要件を満たす必要があるため、cim-server は独自のデータを登録センターに公開する必要があります。 したがって、アプリケーションが正常に起動した後、そのアプリケーション独自のデータを Zookeeper に登録する必要があります。 主な目的は、現在のアプリケーションの IP + CIM サーバー ポート + http ポートを登録することです。 上の図は、デモ環境に登録された 2 つの cim-server インスタンスを示しています (同じサーバー上にあるため、ポートのみが異なります)。 このようにして、クライアント(この Zookeeper ノードをリッスンしている)は、現在利用可能なサービス情報をリアルタイムで知ることができます。 ログイン クライアントが cim-forward-route のログイン インターフェイスを要求し (詳細は下記を参照)、ビジネス検証を完了すると (日常的に他の Web サイトにログインする場合と同様に)、前のプロセスで示したように、クライアントはサーバーへの長い接続を開始します。 このとき、クライアントは現在の情報がログイン情報であることを示す特別なメッセージを送信します。メッセージを受信した後、サーバーはクライアントのユーザー ID と現在のチャネル関係を保存する必要があります。 また、ユーザーID とユーザー名などのユーザー情報もキャッシュします。 オフライン クライアントが切断された場合、キャッシュされた情報もクリアする必要があります。 同時に、関連情報をクリアするために Route インターフェースを呼び出す必要もあります (具体的なインターフェースについては以下を参照してください)。 IMルーティング アーキテクチャ図からわかるように、ルーティング層は非常に重要なリンクです。クライアントとサーバーを接続するための一連の HTTP サービスを提供します。現在、主なインターフェースは次のとおりです。 ①登録インターフェース 各クライアントは使用する前にログインする必要があるため、最初のステップは当然登録です。 ここでの設計は比較的シンプルで、Redis を直接使用してユーザー情報を保存します。ユーザー情報にはIDとユーザー名のみが含まれます。 クエリを容易にするために、Redis の KV は VK を順番に保存するため、ID と userName の両方が一意である必要があります。 ②ログインインターフェース ここでのログインは cim-server のログインとは異なり、ビジネス上の性質を持ちます。
1 人のユーザーだけがログインできるようにするために、Redis の Set を使用してログイン情報を保存します。 userID をキーとして使用すると、重複したログインの書き込みは失敗します。 Java の HashSet と同様に、重複のないデータのみを保存できます。 利用可能なルーティング インスタンスを取得することも比較的簡単です。
もちろん、Zookeeper でサービス インスタンスを取得する前に、cim-server が以前に登録したノードをリッスンする必要があります。 具体的なコードは次のとおりです。 また、アプリケーションの起動後に Zookeeper 内のルーティング ノードを監視し、変更が発生すると内部キャッシュを更新します。 ここでは、Concurrent HashMap に基づく Guava のキャッシュが使用されているため、キャッシュのクリアと追加の原子性が保証されます。 ③グループチャットインターフェース これは実際のメッセージ送信インターフェースです。その結果、1 つのクライアントがメッセージを送信すると、他のすべてのクライアントがそのメッセージを受信できるようになります。 プロセスは、クライアントがサーバーにメッセージを送信することです。サーバーはそれを受信すると、上で紹介した SessionSocketHolder 内のすべてのチャネルをトラバースし、メッセージを送信します。 サーバーは単一のマシンでも構いませんが、現在はクラスター設計になっています。したがって、すべてのクライアントは、以前のポーリング アルゴリズムに従って、異なる cim-server インスタンスに割り当てられます。 したがって、ルーティング層が次のような役割を果たす必要があります。 メッセージを受信した後、ルーティング インターフェイスはまずすべてのクライアントとサービス インスタンス間の関係を走査します。ルーティング関係は次のように Redis に保存されます。 Redis はシングルスレッドであるため、データ量が多い場合は、すべての cim-route:* データと一致するように Keys が使用されると、Redis は他のリクエストを処理できなくなります。 したがって、ここでは Scan コマンドを使用してすべての cim-route:* を走査します。次に、各クライアントが配置されているサーバーの HTTP インターフェースが 1 つずつ呼び出され、メッセージがプッシュされます。 cim-server での実装は次のとおりです。 メッセージを受信した後、cim-server はユーザー ID のチャネルの内部キャッシュを照会し、メッセージを送信します。 ④オンラインユーザーインターフェース これは、現在のオンライン ユーザー情報を照会できる補助インターフェイスです。 実装も非常にシンプルで、以前に「ユーザー ログイン ステータス」を保存したものを照会してリセットするだけです。 ⑤プライベートチャットインターフェース オンラインユーザーを取得することが補助的なインターフェースである理由は、実際にはプライベートチャットを支援するために使用されるためです。 一般的に、プライベート チャットを使用する前に、現在オンラインになっているユーザーを把握する必要があります。そうすれば、誰とプライベート チャットをしたいかがわかります。 次のようなものです: このシナリオでは、プライベート チャットの前提条件は、オンライン ユーザーのユーザー ID を取得することです。 したがって、メッセージを受信した後、プライベート チャット インターフェイスは受信者がいる cim-server インスタンス情報を照会する必要があり、その後の手順はグループ チャットと同じです。情報を送信するには、受信者が配置されているインスタンスの HTTP インターフェイスを呼び出します。 唯一の違いは、グループ チャットはすべてのオンライン ユーザーに送信されるのに対し、プライベート チャットは 1 人のユーザーにのみ送信されることです。 ⑥オフラインインターフェース クライアントがオフラインになると、Redis に以前保存された一部の情報 (ルーティング情報、ログイン ステータス) を削除する必要があります。 IM クライアント クライアント内のロジックの一部については、実際に上記で説明しました。 ログイン 最初のステップはログインです。起動時に Route のログイン インターフェイスを呼び出して、cim-server 情報を取得し、接続を作成する必要があります。 ログイン プロセス中に、ルート インターフェイスは繰り返しログインかどうかを判断します。繰り返しログインした場合は、プログラムはそのまま終了します。 次のステップは、ルート インターフェイスによって返される cim-server インスタンス情報 (ip+port) を使用して接続を作成することです。 最初のステップは、クライアントとチャネル間の関係を維持できるように、サーバーにログイン メッセージを送信することです。 カスタムプロトコル 上記のログイン メッセージと実際のメッセージは、カスタム プロトコルで区別できます。 エンコードとデコードには Google Protocol Buffer が使用されるので、まずは元の形式を見てみましょう。 実際、このプロトコルには現在 3 つのフィールドがあります。
現在、さまざまなビジネスに対応する 3 つの主要なタイプがあります。 ハートビート クライアントとサーバー間の接続を維持するために、メッセージが送信されていない場合は、ハートビートを定期的に自動的に送信する必要があります。 現在の戦略は、1 分ごとにハートビート パケットをサーバーに送信することです。 この方法では、サーバーはビジネス メッセージを受信しない場合、1 分ごとに Ping ハートビート パケットを受信します。 組み込みコマンド クライアントには、使いやすさを考慮していくつかの基本的なコマンドも組み込まれています。 たとえば、:q と入力すると、クライアントが終了し、一部のシステム リソースがシャットダウンされます。 :olu (onlineUser の略) を入力すると、ルートが呼び出され、すべてのオンライン ユーザー インターフェイスが取得されます。 グループチャット グループチャットの使い方はとても簡単です。コンソールにメッセージを入力して Enter キーを押すだけです。このとき、Route のグループ チャット インターフェイスが呼び出されます。 プライベートチャット プライベート チャットでも同様ですが、前提条件としてキーワードをトリガーする必要があります。ユーザーIDを使用します。この形式のメッセージ コンテンツは特定のユーザーにメッセージを送信するために使用されるため、通常は、便利に使用する前に :olu コマンドを使用してすべてのオンライン ユーザーを取得する必要があります。 メッセージコールバック メッセージの保存の必要性など、いくつかのカスタマイズされた要件を満たすため。したがって、クライアントはメッセージを受信した後、実装をカスタマイズできるインターフェースをコールバックします。 したがって、最初に Caller Bean が作成されます。この Bean には CustomMsgHandleListener インターフェースが含まれています。自分で処理する必要がある場合は、このインターフェースを実装するだけで済みます。 インターフェースをカスタマイズする 私はインターフェースを書くのがあまり得意ではないので、インターフェースを書くことができる他の専門家がいると確信しています。したがって、グループ チャット、プライベート チャット、オンライン ユーザー獲得、メッセージ コールバック、およびクライアント内のその他のサービス (および後続のサービス) はすべて、インターフェイスの形式で提供されます。 後からページを統合する場合にも便利です。これらのインターフェースを調整するだけで済みます。具体的な実装について心配する必要はありません。 要約する Cim は現在最新バージョンに過ぎず、バグが多く、機能も少ないです (テストを行うよう招待されたのは数人のグループ メンバーだけです)。ただし、後で改善される予定です。少なくともこのバージョンは、関連する経験がない友人にいくつかのアイデアをもたらすでしょう。 次のステップ: |
<<: rust-vmm で未来の仮想化アーキテクチャを構築する
>>: 10年ぶりのアリババクラウドの新たなスタートを理解する
[[254606]]合併、買収、再編は市場の活動を判断するための重要な基準です。そこで、本稿では、2...
現代社会は消費社会の段階に入っています。これは軽蔑的な言葉ではなく、消費が社会の主な活動となっている...
インターネット上の情報は散在しており、特定のページにおける問題の説明や解決策が不完全です。オリジナル...
Linux ネットワーク仮想化は、LXC プロジェクトのサブプロジェクトです。 LXC には、ファイ...
人を鏡として使うと、自分の得失を理解するのに役立ちます。成功しているサイトを真似して学ぶことで、他の...
ウェブサイトの設計者が最も気にするのは、「1 インチのスペースも貴重」なホームページの価値を最大化す...
世界最大の中国の検索エンジンである百度は、常に高い利用率を誇っています。同社の製品の多くは、ウェブマ...
ImpactVPS では、安価な VPS プロモーションを実施しています。通常の VPS とは異なり...
ウェブサイトがキーワードを正しく選択しているかどうかによって、ウェブサイトの成功または失敗が決まりま...
Hawkhost は、ロサンゼルス データ センターのホストのプロモーションを開始しました (このプ...
前回の2つの記事「Weiboマーケティング戦略の実践経験の共有(パート1)」と「Weiboマーケティ...
チャネル数の増加に伴い、CP の選択肢はますます増えています。しかし、チャネルの品質は多くの CP ...
クラウド コンピューティングは些細なことのように聞こえるかもしれませんが、環境に与える影響は非常に現...
2019 年はあっという間に過ぎ去りましたが、マーケティングの世界では、良い意味でも悪い意味でも考え...
Qunar.com は昨日、同業他社から公に批判された。マフェンウォ・トラベル・ネットワークのチェン...