毎日 5,000 万人のユーザーがいるチャット システムを設計する方法

この記事は最初に公式アカウントで公開されました: さらなる AI (power_ai)、注目を歓迎します、プログラミングと AI 乾物は間に合うように配達されます!

この章では、チャット システムの設計について説明します。ほぼ全員がチャットアプリを使用しています。図 12-1 は、市場で最も人気のあるアプリケーションの一部を示しています。

画像-20230525202809605

チャット アプリは、人によって異なる機能を提供します。特定のニーズを特定することが重要です。たとえば、面接官が 1 対 1 のチャットを考えているときに、グループ チャットに重点を置いたシステムを設計する必要はありません。機能要件を検討することが重要です。

ステップ 1 - 問題を理解し、設計範囲を決定する

設計しているチャット アプリケーションの種類を決定することは非常に重要です。市場には、Facebook Messenger、WeChat、WhatsApp などの 1 対 1 のチャット アプリ、グループ チャットに重点を置いた Slack などのオフィス チャット アプリ、大規模なグループの対話と低遅延音声に重点を置いた Discord のようなゲーム チャット アプリがあります。チャット。

最初の明確な質問では、面接官があなたにチャット システムの設計を依頼したときに正確に何を考えていたのかを明らかにする必要があります。少なくとも、1 対 1 のチャット アプリとグループ チャット アプリのどちらのデザインに重点を置くべきかを判断する必要があります。次のような質問が考えられます。

候補者: どのようなチャット アプリケーションを設計すればよいでしょうか? 1対1ですか、それともグループベースですか?
インタビュアー: 1 対 1 およびグループ チャットをサポートする必要があります。

候補者: これはモバイル アプリですか? それともWebアプリケーションでしょうか?または両方?
インタビュアー: 両方です。

候補者: このアプリケーションの規模はどれくらいですか? それはスタートアップアプリケーションですか、それとも大規模ですか?
インタビュアー: 5,000 万人のデイリー アクティブ ユーザー (DAU) をサポートする必要があります。

候補者: グループ チャットの場合、グループ メンバーの制限は何人ですか?
面接官:100名まで。

候補者: チャット アプリケーションにとって重要な機能は何ですか? 添付ファイルはサポートされますか?
インタビュアー: 1 対 1 のチャット、グループ チャット、プレゼンス インジケーター。システムはテキスト メッセージのみをサポートします。

候補者: メッセージ サイズの制限はありますか?
インタビュアー: はい、テキストの長さは 100,000 文字未満にする必要があります。

候補者: エンドツーエンドの暗号化が必要ですか?
インタビュアー: 今すぐではありませんが、時間が許せば話し合います。

候補者: チャットのログはどのくらいの期間保存する必要がありますか?
インタビュアー: 永遠に。

この章では、Facebook メッセンジャーに似たチャット アプリケーションの設計に焦点を当て、次の機能を強調します。

  • 配信遅延が少ない 1 対 1 のチャット
  • 少人数のグループチャット(最大100人)
  • オンラインステータス
  • 複数のデバイスのサポート。同じアカウントで同時に複数のアカウントにログインできます。
  • プッシュ通知

デザインのサイズを決めることも重要です。5,000万DAUをサポートするシステムを設計します。

ステップ 2 - 大まかな設計を提案し、賛同を得る

高品質のデザインを開発するには、クライアントとサーバー間の通信についての基本を理解しておく必要があります。チャット システムでは、クライアントはモバイル アプリケーションまたは Web アプリケーションになります。クライアントは互いに直接通信しませんが、各クライアントは上記のすべてをサポートするチャット サービスに接続します。基本的な操作を中心に見ていきましょう。チャット サービスは次の機能をサポートする必要があります。

  • 他のクライアントからメッセージを受信します。
  • 各メッセージの正しい受信者を見つけて、メッセージを受信者に転送します。
  • 受信者がオンラインでない場合、メッセージは受信者がオンラインになるまでサーバー上に保持されます。

図 12-2 は、クライアント (送信者および受信者) とチャット サービスの関係を示しています。

画像-20230525202830712

クライアントがチャットを開始しようとすると、1 つ以上のネットワーク プロトコルを使用してチャット サービスに接続します。チャット サービスの場合、ネットワーク プロトコルの選択は非常に重要です。これについて面接官と話し合いましょう。

ほとんどのクライアント/サーバー アプリケーションでは、リクエストはクライアントによって開始されます。これは、チャット アプリケーションの送信側にも当てはまります。図 12-2 では、送信者がチャット サービス経由で受信者にメッセージを送信するときに、最も一般的な Web プロトコルである実績のある HTTP プロトコルを使用します。このシナリオでは、クライアントがチャット サービスとの HTTP 接続を確立してメッセージを送信し、通知サービスがそのメッセージを受信者に送信します。キープアライブ ヘッダーによりクライアントはチャット サービスとの永続的な接続を維持できるため、キープアライブはこの点で非常に効率的です。また、TCP ハンドシェイクの数も削減されます。送信側では HTTP が適切な選択であり、Facebook [1] などの多くの人気のあるチャット アプリケーションは当初、メッセージの送信に HTTP を使用していました。

ただし、受信側はもう少し複雑です。HTTP はクライアントによって開始されるため、サーバーからメッセージを送信することは簡単ではありません。長年にわたり、人々はポーリング、ロング ポーリング、WebSocket など、サーバーによって開始される接続をシミュレートするためにさまざまな手法を使用してきました。これらはすべて、システム設計のインタビューで広く使用されている重要なテクニックです。見てみましょう。

投票

図 12-3 に示すように、ポーリングは、クライアントがサーバーにメッセージが利用可能かどうかを定期的に問い合わせる手法です。ポーリングの頻度によっては、ポーリングがリソースを大量に消費する可能性があります。ほとんどの場合、質問に「いいえ」と答えると、貴重なサーバー リソースが消費される可能性があります。

画像-20230525202847465

ロングポーリング

ポーリングは非効率的な場合があるため、次の進歩はロング ポーリングです (図 12-4 を参照)。

画像-20230525202903376

ロングポーリングでは、クライアントは、新しいメッセージが利用可能になるか、タイムアウトしきい値に達するまで、接続を開いたままにします。クライアントは新しいメッセージを受信するとすぐに別のリクエストをサーバーに送信し、プロセスを最初からやり直します。ロングポーリングにはいくつかの欠点があります。

  • 送信者と受信者は同じチャット サーバーに接続できません。HTTP ベースのサーバーは通常、ステートレスです。ロード バランシングにラウンド ロビンを使用する場合、メッセージを受信するサーバーは、メッセージを受信するクライアントとのロング ポーリング接続を確立できない可能性があります。
  • サーバーには、クライアントが切断されたかどうかを知る良い方法がありません。
  • それは非効率的です。ユーザーが頻繁にチャットしない場合でも、タイムアウト後も長いポーリングによって定期的な接続が確立されます。

ウェブソケット

WebSocket は、サーバーからクライアントに非同期更新を送信するための最も一般的なソリューションです。図 12-5 は、その仕組みを示しています。

画像-20230525202917789

WebSocket 接続はクライアントによって開始されます。これは双方向で永続的です。これは HTTP 接続として開始され、明確に定義されたハンドシェイク プロトコルを使用して WebSocket 接続に「アップグレード」できます。この永続的な接続を通じて、サーバーはクライアントに更新を送信できます。ファイアウォールが存在する場合でも、WebSocket 接続は通常は正常に機能します。これは、HTTP/HTTPS 接続でも使用されるポート 80 または 443 を使用しているためです。

HTTP は送信側で優れたプロトコルであると前述しましたが、WebSocket は双方向であるため、送信側でも WebSocket を使用しない技術的な強い理由はありません。図 12-6 は、送信側と受信側の両方で WebSocket (ws) を使用する方法を示しています。

画像-20230525202932373

送信側と受信側の両方で WebSocket を使用することにより、設計が簡素化され、クライアント側とサーバー側での実装がより簡単になります。WebSocket 接続は永続的であるため、サーバー側での効率的な接続管理が重要です。

先進的なデザイン

先ほど、WebSocket がクライアントとサーバー間の主要な通信プロトコルとして選択されたと述べました。WebSocket には双方向通信の特性があります。他のすべてで WebSocket を使用する必要はないことに注意することが重要です。実際、チャット アプリケーションのほとんどの機能 (登録、ログイン、ユーザー プロファイルなど) は、HTTP 経由の従来の要求/応答メソッドを使用して実行できます。もう少し深く掘り下げて、システムの高レベルのコンポーネントを見てみましょう。

図 12-7 に示すように、チャット システムは、ステートレス サービス、ステートフル サービス、サードパーティ統合という 3 つの主なカテゴリに分類されます。

画像-20230525202948036

ステートレスサービス

ステートレス サービスは、ログイン、登録、ユーザー プロファイルなどを管理する、従来の公開要求/応答サービスです。これらは多くの Web サイトやアプリに共通の機能です。

ステートレス サービスはロード バランサーの背後にあり、ロード バランサーの仕事は、リクエスト パスに基づいてリクエストを正しいサービスにルーティングすることです。これらのサービスは、単一のマイクロサービスまたは個別のマイクロサービスにすることができます。これらのステートレス サービスの多くは、市場に簡単に統合できるものがあるため、自分で構築する必要はありません。詳細な説明で詳しく説明するサービスの 1 つは、サービス ディスカバリです。その主な仕事は、クライアントが接続できるチャット サーバーの DNS ホスト名のリストをクライアントに提供することです。

ステートフルサービス

唯一のステートフル サービスはチャット サービスです。各クライアントがチャット サーバーへの永続的なネットワーク接続を維持するため、このサービスはステートフルです。このサービスでは、サーバーがまだ利用可能な限り、クライアントは通常、別のチャット サーバーに切り替えることはありません。サービス検出はチャット サービスと密接に連携して、サーバーの過負荷を回避します。これについては、詳細な調査で詳しく説明します。

サードパーティの統合

チャット アプリの場合、プッシュ通知は最も重要なサードパーティ統合です。これは、アプリが実行されていない場合でも、新しいメッセージが到着したときにユーザーに通知する方法でもあります。プッシュ通知を適切に統合することが重要です。詳細については、第 10 章「通知システムの設計」を参照してください。

スケーラビリティ

小規模であれば、上記のサービスはすべて 1 台のサーバーに収まります。私たちが設計した規模でも、理論的にはすべてのユーザー接続を単一の最新のクラウド サーバーに収めることが可能です。サーバーが処理できる同時接続の数が制限要因となる可能性が最も高くなります。このシナリオでは、同時ユーザー数が 100 万人で、各ユーザー接続がサーバー上で 10K のメモリを必要とすると仮定すると (これは非常に大まかな数字であり、言語の選択に大きく依存します)、すべての接続を 1 つに保存するのに必要なメモリは約 10GB だけです。箱。

すべてが 1 つのサーバーに収まる設計を思いついた場合、面接官の心に大きな危険信号が生じる可能性があります。単一サーバー上でこれほどの規模を設計した技術者はいないでしょう。単一サーバーの設計は、多くの要因により大きな変革をもたらします。単一障害点はその中で最大のものです。

ただし、単一サーバー設計から始めることはまったく問題ありません。面接官には、これが単なる出発点であることを理解してもらいましょう。これまで述べてきたことをすべてまとめると、図 12-8 は調整された高レベルの設計を示します。

画像-20230525203007564

図 12-8 では、クライアントはリアルタイム メッセージングのためにチャット サーバーへの永続的な WebSocket 接続を維持します。

  • チャット サーバーを使用すると、メッセージの送受信が容易になります。
  • プレゼンスサーバーはオンライン/オフライン状態を管理します。
  • API サーバーは、ユーザーのログイン、登録、プロファイルの変更などを含むすべてを処理します。
  • 通知サーバーはプッシュ通知を送信します。
  • 最後に、Key-Value ストアを使用してチャット履歴を保存します。オフライン ユーザーがオンラインになると、以前のチャット履歴がすべて表示されます。

保管所

この段階までに、サーバーの準備が整い、サービスが稼働し、サードパーティの統合が完了します。テクノロジー スタックの奥深くにあるのがデータ層です。データ レイヤーを適切に処理するには、多くの場合、ある程度の努力が必要です。リレーショナル データベースと NoSQL データベースのどちらの種類のデータベースを選択するかという重要な決定を下す必要があります。情報に基づいた決定を下すために、データ型と読み取り/書き込みモードを調べます。

一般的なチャット システムには 2 種類のデータがあります。1つ目は、ユーザープロフィール、設定、ユーザーフレンドリストなどの一般的なデータです。これらのデータは、堅牢で信頼性の高いリレーショナル データベースに保存されます。レプリケーションとシャーディングは、可用性とスケーラビリティの要件を満たすために使用される一般的な技術です。

2 つ目は、チャット システム固有のデータであるチャット履歴データです。読み取り/書き込みモードを理解することが非常に重要です。

  • チャットシステムのデータ量は膨大です。以前の調査 [2] では、Facebook メッセンジャーと Whatsapp が 1 日に 600 億のメッセージを処理していることが示されています。
  • 最近のチャットのみが頻繁にアクセスされます。通常、ユーザーは古いチャットを探しません。
  • ほとんどの場合、最近のチャット履歴を表示しますが、ユーザーは検索、メンションの表示、特定のメッセージへのジャンプなど、データへのランダム アクセスを必要とする一部の機能を使用する場合があります。データ アクセス層はこれらのケースをサポートする必要があります。
  • 1 対 1 のチャット アプリケーションの場合、読み取りと書き込みの比率は約 1:1 です。

すべてのユースケースをサポートする適切なストレージ システムを選択することが重要でした。次の理由から、キーと値のストレージをお勧めします。

  • Key-Value ストアにより、簡単な水平スケーリングが可能になります。
  • キーと値のストアでは、データ アクセスの待ち時間が非常に短くなります。
  • リレーショナル データベースはデータのロングテールをうまく処理できません [3]。インデックスが大きくなると、ランダム アクセスのコストが高くなります。
  • Key-Value ストレージは、他の実証済みの信頼性のあるチャット アプリケーションで採用されています。たとえば、Facebook メッセンジャーと Discord は両方とも Key-Value ストアを使用します。Facebook メッセンジャーは HBase[4] を使用し、Discord は Cassandra[5] を使用します。

データ・モデル

先ほど、ストレージ レイヤーとしてキーバリュー ストアを使用することについて説明しました。最も重要なデータはメッセージ データです。詳しく見てみましょう。

1対1のチャットメッセージフォーム

図 12-9 は、1 対 1 チャットのメッセージ テーブルを示しています。主キーはmessage_idで、メッセージの順序を決定するために使用されます。2 つのメッセージが同時に作成される可能性があるため、created_atに依存してメッセージの順序を決定することはできません。

画像-20230525203030794

グループチャットメッセージテーブル

図 12-10 は、グループ チャットのメッセージ テーブルを示しています。複合主キーは(channel_id, message_id) で、ここでチャンネルとグループは同じ意味です。グループ チャット内のすべてのクエリは 1 つのチャネルで行われるため、 channel_idはパーティション キーです。

画像-20230525203043351

メッセージID

message_idを生成する方法は、議論する価値のある興味深いトピックです。Message_id は、メッセージの順序を保証する責任を負います。メッセージの順序を決定するには、message_id が次の 2 つの要件を満たしている必要があります。

  • ID は一意である必要があります。
  • ID は時間順に並べ替える必要があります。つまり、新しい行は古い行よりも高い ID を持ちます。

これら 2 つの保証をどのように達成するのでしょうか? 最初に思い浮かぶのは、 MySql の「 auto_increment 」キーワードです。ただし、NoSQL データベースは通常、そのような機能を提供しません。

2 番目の方法は、Snowflake [6] のようなグローバル 64 ビット シリアル番号ジェネレーターを使用することです。これについては、「第 7 章: 分散システムにおける一意の ID ジェネレーターの設計」で説明します。

最後の方法は、ローカルのシリアル番号ジェネレーターを使用することです。ローカルとは、ID がグループ内でのみ一意であることを意味します。ローカル ID が機能する理由は、1 対 1 チャネル内またはグループ チャネル内でメッセージの順序を維持するのに十分だからです。このアプローチは、グローバル ID の実装よりも実装が簡単です。

ステップ 3 - 詳細な設計

システム設計の面接では、通常、高レベルの設計の特定のコンポーネントにドリルダウンすることが期待されます。チャット システムの場合、サービス ディスカバリ、メッセージ フロー、オンライン/オフライン インジケーターについて詳しく調べる価値があります。

サービスディスカバリ

サービス ディスカバリの主な役割は、地理的位置、サーバー容量などの基準に基づいて、クライアントに最適なチャット サーバーを推奨することです。Apache Zookeeper [7] は、人気のあるオープンソース サービス検出ソリューションです。利用可能なすべてのチャット サーバーを登録し、あらかじめ決められた基準に基づいてクライアントに最適なチャット サーバーを選択します。

図 12-11 は、サービス検出 (Zookeeper) がどのように機能するかを示しています。

画像-20230525203108930

  1. ユーザー A がアプリケーションにログインしようとします。
  2. ロードバランサーはログインリクエストを API サーバーに送信します。
  3. バックエンドがユーザーを認証した後、サービス検出によってユーザー A に最適なチャット サーバーが検索されます。この例では、サーバー 2 が選択され、サーバー情報がユーザー A に返されます。
  4. ユーザー A は WebSocket 経由でチャット サーバー 2 に接続します。

メッセージフロー

チャット システムのエンドツーエンドの流れを理解するのは興味深いことです。このセクションでは、1 対 1 のチャット フロー、複数のデバイス間でのメッセージの同期、およびグループ チャット フローについて説明します。

1対1のチャットプロセス

図 12-12 は、ユーザー A がユーザー B にメッセージを送信すると何が起こるかを説明しています。

画像-20230525203124205

  1. ユーザー A がチャット メッセージをチャット サーバー 1 に送信します。
  2. チャット サーバー 1 は、ID ジェネレーターからメッセージ ID を取得します。
  3. チャット サーバー 1 はメッセージをメッセージ同期キューに送信します。
  4. メッセージはキーと値のストアに保存されます。
    5.a. ユーザー B がオンラインの場合、メッセージはユーザー B が接続しているチャット サーバー 2 に転送されます。
    5.b. ユーザー B がオフラインの場合、プッシュ通知 (PN) サーバーはプッシュ通知を送信します。
  5. チャット サーバー 2 はメッセージをユーザー B に転送します。ユーザー B とチャット サーバー 2 の間には永続的な WebSocket 接続があります。

複数のデバイス間でのメッセージの同期

多くのユーザーは複数のデバイスを持っています。複数のデバイス間でメッセージを同期する方法について説明します。図 12-13 に、メッセージ同期の例を示します。

画像-20230525203139220

図 12-13 では、ユーザー A は携帯電話とラップトップという 2 つのデバイスを持っています。ユーザー A が携帯電話でチャット アプリケーションにログインすると、チャット サーバー 1 との WebSocket 接続が確立されます。同様に、ラップトップとチャット サーバー 1 の間に接続があります。

各デバイスは、デバイス上の最新のメッセージ ID を追跡するcur_max_message_idという変数を維持します。次の 2 つの条件を満たす場合、メッセージは新しいとみなされます。

  • 受信者 ID は、現在ログインしているユーザー ID と同じです。
  • キー/値ストア内のメッセージ ID がcur_max_message_idより大きいです。

cur_max_message_id はデバイスごとに異なるため、各デバイスは KV ストアから新しいメッセージをフェッチできるため、メッセージの同期が簡単になります。

少人数のグループチャットプロセス

1 対 1 のチャットと比較して、グループ チャットのロジックはより複雑です。図 12-14 および 12-15 は、このフローを示しています。

画像-20230525203156340

図 12 ~ 14 は、ユーザー A がグループ チャットでメッセージを送信すると何が起こるかを説明しています。グループに 3 人のメンバー (ユーザー A、ユーザー B、ユーザー C) がいるとします。まず、ユーザー A のメッセージが各グループ メンバーのメッセージ同期キューにコピーされます。1 つはユーザー B 用、もう 1 つはユーザー C 用です。メッセージ同期キューは受信者の受信箱と考えることができます。この設計の選択は、次の理由から少人数のグループ チャットに適しています。

  • 各クライアントは自分の受信箱で新しいメッセージを確認するだけでよいため、メッセージ同期プロセスが簡素化されます。
  • グループのサイズが小さい場合は、各受信者の受信トレイにコピーを保存するのにそれほど費用はかかりません。

WeChat も同様のアプローチを採用しており、グループのメンバー数を 500 人に制限しています [8]。ただし、多数のユーザーがいるグループの場合、メンバーごとにメッセージのコピーを保存することは受け入れられません。

受信者側では、受信者は複数のユーザーからメッセージを受信できます。各受信者には、さまざまな送信者からのメッセージが含まれる受信箱 (メッセージ同期キュー) があります。図 12-15 にこの設計を示します。

画像-20230525203219073

オンラインステータス

プレゼンス インジケーターは、多くのチャット アプリケーションの重要な機能です。通常、ユーザーのプロフィール写真またはユーザー名の横に緑色の点が表示されます。このセクションでは、舞台裏で何が起こっているのかについて説明します。

高レベルの設計では、プレゼンス サーバーはプレゼンスの管理と、WebSocket を介したクライアントとの通信を担当します。オンラインステータスの変更をトリガーするプロセスがいくつかあります。それぞれを見てみましょう。

ユーザーログイン

ユーザーのログインプロセスについては、「サービスディスカバリ」セクションで説明されています。クライアントとリアルタイム サービスの間に WebSocket 接続が確立された後、ユーザー A のオンライン ステータスとlast_active_atタイムスタンプが KV ストレージに保存されます。ユーザーがログインすると、ステータス インジケーターにユーザーがオンラインであることが示されます。

画像-20230525203233126

ユーザーのログアウト

ユーザーがログアウトすると、図 12-17 に示すユーザー ログアウト プロセスが実行されます。KV ストレージのオンライン状態がオフラインに変更されます。ステータス インジケーターは、ユーザーがオフラインであることを示します。

画像-20230525203246006

ユーザーが切断されました

私たちは皆、インターネット接続が継続的で信頼性の高いものであることを望んでいます。ただし、常にそうであるとは限らないため、設計でこれに対処する必要があります。ユーザーがインターネットから切断すると、クライアントとサーバー間の永続的な接続が失われます。ユーザーの切断を処理する簡単な方法は、ユーザーをオフラインとしてマークし、接続が再確立されたときにステータスをオンラインに変更することです。ただし、このアプローチには大きな欠陥があります。ユーザーが短期間にインターネットへの接続を頻繁に切断し、再接続することは非常に一般的です。たとえば、ユーザーがトンネルを通過している間、ネットワーク接続が断続的になる可能性があります。切断/再接続のたびにプレゼンス ステータスを更新すると、ステータス インジケーターが頻繁に変化し、ユーザー エクスペリエンスが低下します。

この問題を解決するためにハートビート メカニズムを導入します。オンライン クライアントは定期的にハートビート イベントを状態サーバーに送信します。状態サーバーが一定時間内 (たとえば x 秒以内) にクライアントからハートビート イベントを受信した場合、ユーザーはオンラインであるとみなされます。それ以外の場合はオフラインです。

画像-20230525203259161

図 12-18 では、クライアントは 5 秒ごとにハートビート イベントをサーバーに送信します。3 つのハートビート イベントを送信した後、クライアントは切断され、x = 30 秒間再接続されません (この数値はロジックを示すために任意に選択されました)。オンラインステータスがオフラインに変更されます。

プレゼンス拡散

ユーザー A の友人はステータスの変更をどのようにして知るのでしょうか? 図 12-19 は、その仕組みを説明しています。状態サーバーは、友人の各ペアがチャネルを維持するパブリッシュ/サブスクライブ モデルを使用します。ユーザー A のオンライン ステータスが変化すると、チャネル AB、AC、AD の 3 つのチャネルにイベントを発行します。これら 3 つのチャネルは、それぞれユーザー B、C、D によって購読されています。そのため、友人はオンラインで最新のステータスを簡単に入手できます。クライアントとサーバー間の通信は、リアルタイム WebSocket 経由で行われます。

画像-20230525203311767

上記の設計は、小規模なユーザー グループに効果的です。たとえば、WeChat はユーザー ベースが 500 人に制限されているため、同様のアプローチを採用しています。大規模なグループの場合、すべてのメンバーにオンライン ステータスを通知するには費用と時間がかかります。グループに 100,000 人のメンバーがいるとします。状態が変化するたびに 100,000 のイベントが生成されます。パフォーマンスのボトルネックを解決するために考えられる解決策の 1 つは、ユーザーがグループに入るとき、または友人リストを手動で更新したときにのみオンライン ステータスを取得することです。

ステップ 4 - まとめ

この章では、1対1のチャットと少人数のグループチャットをサポートするチャットシステムのアーキテクチャを紹介します。WebSocket は、クライアントとサーバー間のリアルタイム通信に使用されます。チャット システムは、リアルタイム メッセージング用のチャット サーバー、オンライン ステータスを管理するためのステータス サーバー、プッシュ通知を送信するためのプッシュ通知サーバー、チャット履歴を永続化するための Key-Value ストア、およびその他の機能。

面接の終わりに時間に余裕がある場合は、追加の議論のポイントを以下に示します。

  • チャット アプリケーションを拡張して、写真やビデオなどのメディア ファイルをサポートします。メディア ファイルのサイズはテキストよりもはるかに大きくなります。圧縮、クラウド ストレージ、サムネイルは、議論する価値のある興味深いトピックです。
  • エンドツーエンドの暗号化。Whatsapp はメッセージのエンドツーエンド暗号化をサポートしています。送信者と受信者のみがメッセージを読むことができます。興味のある読者は、参考文献の記事 [9] を参照してください。
  • クライアント側でメッセージをキャッシュすると、クライアントとサーバー間のデータ転送を効果的に削減できます。
  • ロード時間を改善します。Slack は地理的に分散したネットワークを構築し、ユーザー データやチャネルなどをキャッシュして読み込み時間を改善します [10]。
  • エラー処理。
    • チャットサーバーエラー。チャット サーバーには数十万以上の永続的な接続が存在する場合があります。チャット サーバーがオフラインになった場合、サービス ディスカバリ (Zookeeper) は、クライアントが新しい接続を確立するための新しいチャット サーバーを提供します。
    • メッセージ再送信メカニズム。再試行とキューイングは、メッセージを再送信するための一般的な手法です。

ここまで到達できておめでとうございます! 今すぐ自分を叱咤激励してください。どうぞ!

参考文献


[ 1] Facebook の Erlang: https://www.erlang-factory.com/upload/presentations/31/EugeneLetuchy-ErlangatFacebook.pdf

[2] Messengerと WhatsApp は 1 日あたり 600 億のメッセージを処理します:
https://www.theverge.com/2016/4/12/11415198/facebook-messenger-whatsapp-number-messages-vs-sms-f8-2016

[3] ロングテール効果: https://en.wikipedia.org/wiki/Long_tail

[4] メッセージの基盤となるテクノロジー:
https://www.facebook.com/notes/facebook-engineering/the-underlying-technology-of-messages/454991608919/


[5] Discord が数十億のメッセージを保存する方法: https://blog.discordapp.com/how-discord-stores-billions-of-messages-7fa6ec7ee4c7


[6] TwitterのSnowflake システム リリースのお知らせ: https://blog.twitter.com/engineering/en_us/a/2010/owned-snowflake.html

[7] Apache ZooKeeper: https://zookeeper.apache.org/

[8] ゼロから: WeChat バックグラウンド システムの進化 (中国語記事):
https://www.infoq.cn/article/the-road-of-the-growth-weixin-background

[9] エンドツーエンド暗号化: https://faq.whatsapp.com/en/android/28030015/

[10] Flannel: Slack をより効率的にするためのアプリケーション レベルのエッジ キャッシュ:
https://slack.engineering/flannel-an-application-level-edge-cache-to-make-slack-scale-b8a6400e2f6b

こんにちは、開発7年、外資系5年、インターネット2年のベテランドライバー、しさんです。アーサンやラオメイには勝てますが、PRコメントでダメになったこともあります。長年にわたり、私はパートタイムで働いたり、起業したり、プライベートな仕事を引き継いだり、仕事を混ぜたりしてきました。お金を儲けたし、お金を失った。その過程で、私が最も深く感じたのは、何を学ぶにしても、学び続けなければならないということです。粘り強く続けることができれば、コーナー追い越しを達成するのは簡単です!だから、私が今やっていることをやるには遅すぎるかどうかは聞かないでください。それでも方向性が分からない場合は、私 [パブリック アカウント: More AI (power_ai)] をフォローしてください。そこでは、コーナリングや追い越しのための資本を蓄積するのに役立つ、最先端の情報やプログラミングの知識を頻繁に共有します。

おすすめ

転載: blog.csdn.net/smarter_AI/article/details/131798105