スケーラブルな通知システムを設計する方法は?[閉まっている]


32

通知システムマネージャーを作成する必要があります。

私の要件は次のとおりです。

異なるプラットフォームで通知を送信できる必要がありますが、これは完全に異なる場合があります(たとえば、SMSまたはEメールのいずれかを送信できる必要があります)。

通知は、特定のプラットフォームのすべての受信者で同じ場合もありますが、プラットフォームごとの受信者(または複数)ごとの通知である場合もあります。

各通知にはプラットフォーム固有のペイロードを含めることができます(たとえば、MMSにはサウンドまたは画像を含めることができます)。

システムはスケーラブルである必要があり、アプリケーションまたはサーバーをクラッシュさせることなく、非常に大量の通知を送信できる必要があります。

これは2段階のプロセスです。最初に顧客がメッセージを入力し、送信先のプラットフォームを選択します。その後、リアルタイムで処理されるように通知を作成する必要があります。

次に、システムはプラットフォームプロバイダーに通知を送信する必要があります。


今のところ、私はいくつかの結果になりますが、どれだけスケーラブルであるか、またはそれが良いデザインであるかどうかはわかりません。

私は次のオブジェクトを(疑似言語で)しました:

汎用Notificationオブジェクト:

class Notification {
    String                 $message;
    Payload                $payload;
    Collection<Recipient>  $recipients;
}

次のオブジェクトの問題は、受信者が1.000.000だったらどうなりますか?Recipientオブジェクトが非常に小さい場合でも、メモリを大量に消費します。

受信者ごとに1つの通知を作成することもできますが、一部のプラットフォームプロバイダーはバッチで送信する必要があるため、複数の受信者で1つの通知を定義する必要があります。

作成された各通知は、DBやRedisなどの永続ストレージに保存できます。

これを後で集約してスケーラブルであることを確認するのは良いことでしょうか?

2番目のステップで、この通知を処理する必要があります。

しかし、適切なプラットフォームプロバイダーへの通知をどのように区別できますか?

MMSNotification拡張するようなオブジェクトを使用する必要がありabstract Notificationますか?または何かのようなNotification.setType('MMS')

大量の通知を同時に処理できるようにするには、RabbitMQのようなメッセージングキューシステムが適切なツールであると考えています。それは...ですか?

これにより、大量の通知をキューに入れ、複数のワーカーに通知をポップして処理させることができます。しかし、上記のように受信者をバッチ処理する必要がある場合はどうなりますか?

次に、プラットフォームプロバイダーを接続して通知を実行するために、それぞれNotificationProcessor追加できるオブジェクトを担当することを想像します。NotificationHandlerNotificationHandler

を使用しEventManagerて、プラグイン可能な動作を許可することもできます。

フィードバックやアイデアはありますか?

お時間をいただきありがとうございます。

注:私はPHPでの作業に慣れており、おそらく選択した言語です。


編集 (morphunrealの答えによる)

  • 1秒間に送信するメッセージの数(現在/初期レベルを定義し、再設計する前にシステムが処理する必要がある最大レベルを定義します)
  • システムのハードウェア制約(システムで使用可能なメモリ、CPUなど)
  • ハードウェアはどのように拡張されますか(つまり、サーバーの追加、クラウドコンピューティングなど)

  • どの言語/システムが通知を生成しますか?

通知はプログラムで作成しますが、UIから作成するのは私自身です。

  • ジェネレーターはメッセージの受信者を知っていますか(?)、または他の手段で提供されていますか(つまり、特定のアラートタイプのビジネスルールは特定の受信者に送信されます)

特定の受信者、受信者のグループ(たとえば、タグシステムを使用)、またはプラットフォーム全体に対して通知を作成できる必要があります。

  • CC / BCC /開封確認を追加するためのビジネスルールはありますか

はい。これは実際にはプラットフォーム固有であり、readまたはccはすべてのプラットフォームで利用できるわけではないことに注意してください。

  • ジェネレーターは、送信するメッセージの種類(SMS /電子メールなど)を知っていますか、それとも受信者に基づいていますか

受信者に基づいていますが、受信者はプラットフォームに関連しており、プラットフォームがデータを処理する方法が異なるため、UIは画像、音声などを設定できるプラットフォーム固有のものである可能性があります。

  • ジェネレーターは、メッセージの送信/受信/読み取りの確認を必要としますか(非同期送信と同期送信)

システムはエラーを起こしやすいはずですが、エラーを処理して一連のルールを定義する必要があります。たとえば、サーバーに到達できない場合は、通知を再処理してさらに処理する必要がありますが、通知が正しくない場合(またはプラットフォームプロバイダーによってそのまま定義されます)、キューに再登録するのではなく、通知する必要があります。

  • メッセージの送信元/受信者の履歴を保存するための要件はありますか?

はい、私たちはおそらくいくつかの統計とレポートを作りたいです。*通知エンドポイントの定義


  • メッセージの送信に使用されているサービスは何ですか?依存します、いくつかは古典的なRESTウェブサービスであり、他はいくつかのエキゾチックなプロトコルです、それは実際にプロバイダー次第です。

  • 提供されるフィードバック/確認(同期/非同期)

場合によっては、一部は同期してエラーで応答しますが、他の一部はエラーをチェックするために後でプルする必要があります。

  • 新しいエンドポイントを追加する可能性がありますか[追加する場合でも、抽象化する必要があるか]

はい、実際、私たちのアプリは成長しており、新しいプロバイダーを追加できるようにしたいと考えていますが、それは1年に1つか2つの割合です。


22
Walter、gnat、gbjbaanb、Robert Harvey、thorstenmüllerは怠け者のようです。「曖昧、あいまい、不完全、過度に広い、または修辞的」という議論のいずれかが原因で、この質問が閉じられた理由はわかりません。設計に関する質問は、非常に多くのことが関係するため、単純な質問ではありませんが、このウェブサイトのレベルでは、このような複雑な決定を実際の専門家と話し合うことができました。
トレント

質問するが、質問はしないでください!:)ええ、時々私もMODのメンタリティを推測できません。
-Mrchief

賛成票と意見は、この質問がどれほど関連性があるかを示しています。
-NoobEditor

RabbitMQを使用することは、この問題に対する正しいアプローチです。私はBIG企業インタビューの1つで非常によく似た問題を尋ねられ、最高のフォールトトレラントなパブリッシャー/サブスクライバーパターンに苦労していました。最後に、私は正しい答えを言われました。RabbitMQ。彼らはそれを使用して問題を解決したようです。それが役立つことを願っています!!!
AkD

回答:


16

機能要件と非機能要件を区別し、それらを慎重に定義することから始めます。あいまいな要件に基づいてシステムを過剰に設計するのは非常に簡単です。

たとえば、スケーラビリティに関する非機能要件は非常にあいまいです。システムに実際の数値を入力すると、多くの精神的な負担を軽減できます。例えば、

  • 1秒間に送信するメッセージの数(現在/初期レベルを定義し、再設計する前にシステムが処理する必要がある最大レベルを定義します)
  • システムのハードウェア制約(システムで使用可能なメモリ、CPUなど)
  • ハードウェアはどのように拡張されますか(つまり、サーバーの追加、クラウドコンピューティングなど)

これで問題が解決したので、いくつかのテストセットアップして、システムの設計/アーキテクチャが非機能要件を満たしていることを確認できます。

通知/メッセージを送信するビジネス/機能要件に関しては、次の手がかりが役立つ場合があります(この回答に追加できる情報を提供する場合)。

通知ソースを定義する

  • 通知を生成する言語/システム
  • ジェネレーターはメッセージの受信者を知っていますか(?)、または他の手段で提供されていますか(つまり、特定のアラートタイプのビジネスルールは特定の受信者に送信されます)
  • CC / BCC /開封確認を追加するためのビジネスルールはありますか
  • ジェネレーターは、送信するメッセージの種類(SMS /電子メールなど)を知っていますか、それとも受信者に基づいていますか
  • ジェネレーターは、メッセージの送信/受信/読み取りの確認を必要としますか(非同期送信と同期送信)
  • メッセージの送信元/受信者の履歴を保存するための要件はありますか?

通知エンドポイントを定義する

  • メッセージの送信に使用されているサービス
  • 提供されるフィードバック/確認(同期/非同期)
  • 新しいエンドポイントを追加する可能性がありますか[追加する場合でも、抽象化する必要があるか]

関連する要因に大きく依存するため、具体的なアーキテクチャの例を提供するのをためらいます。しかし、多くの場合、最も単純なメッセージシステムには、メモリ/アプリケーション、非SQL、ディスク、またはリレーショナルデータベースの基本キューが含まれます。次に、個別のプロセス(または分散されている場合は複数の個別のプロセス)がメッセージタイプ[cronジョブ]のキューをポーリングできます。必要に応じて送り出します。

メッセージをすぐに送信する必要がある場合は、プッシュベースの手法(PostgreSQL NOTIFY / LISTENなど)を使用してこれを強化することもできます。

単純なキューの利点は、メッセージを生成するシステムが行う作業がほとんどなく、ハードウェア/パフォーマンス要件に基づいて処理システムのバランスを取ることができることです。


実際に明確なアイデアを得るのに役立つ詳細な回答をありがとうございます。回答を編集して、あなたが提起した質問に答えました。
トレント

-2

通知オブジェクトのフライウェイトデザインパターンを検討しましたか?パターンを実装したことがないので、それについてはあまりわかりませんが、フライウェイトオブジェクト間で何らかの状態を共有することを思い出します。また、冗長性の高いメンバーは、共有すると大きな影響を与えたと思います。したがって、少数のメッセージのみを多くの人に送信するか、その逆の場合に依存します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.