web-dev-qa-db-ja.com

スケーラブルな通知システムを設計するには?

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

これが私の要件です:

まったく異なるプラットフォームで通知を送信できるようにする必要があります(たとえば、SMSまたは電子メール)を送信できる必要があります)。

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

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

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

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

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


とりあえず、結局はいくらかで終わりますが、それがどれほどスケーラブルになるか、それが良いデザインかどうかわかりません。

私は(疑似言語で)次のオブジェクトについて考えました:

一般的なNotificationオブジェクト:

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

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

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

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

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

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

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

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

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

それは私が多くの通知をキューに入れ、いくつかのワーカーに通知をポップして処理することを可能にします。しかし、上記のように受信者をバッチ処理する必要がある場合はどうなりますか?

次に、NotificationProcessorオブジェクトを追加できるNotificationHandlerオブジェクトを想像します。各NotificationHandlerは、プラットフォームプロバイダーを接続して通知を実行する役割を果たします。

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

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

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

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


編集(morphunrealの回答による)

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

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

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

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

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

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

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

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

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

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

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

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

はい、いくつかの統計とレポートを作成したいと考えています。 *通知エンドポイントを定義する


  • メッセージの送信にどのサービスが使用されていますか?依存します、いくつかは古典的ですREST webservice、他はいくつかのエキゾチックなプロトコルです、それは本当にプロバイダー次第です。

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

依存しているものもあれば、同期してエラーで応答するものもあれば、後でプルしてエラーをチェックする必要があるものもあります。

  • 新しいエンドポイントを追加する可能性はありますか(そうであっても、抽象化する必要さえありますか)

はい、実際、私たちのアプリは成長しており、新しいプロバイダーを追加できるようにしたいと思うかもしれませんが、それは年に1または2のような比率です。

33
Trent

まず、機能要件と非機能要件を分離し、慎重に定義します。あいまいな要件に基づいてシステムを過剰に設計することは非常に簡単です。

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

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

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

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

通知ソースを定義する

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

通知エンドポイントの定義

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

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

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

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

16
nathan-m