it-swarm.com.de

Wie entwerfe ich ein skalierbares Benachrichtigungssystem?

Ich muss einen Benachrichtigungssystem-Manager schreiben.

Hier sind meine Anforderungen:

Ich muss in der Lage sein, eine Benachrichtigung auf verschiedenen Plattformen zu senden, was völlig unterschiedlich sein kann (zum Beispiel muss ich entweder eine SMS oder eine E-Mail) senden können.

Manchmal kann die Benachrichtigung für alle Empfänger einer bestimmten Plattform gleich sein, manchmal kann es sich jedoch um eine Benachrichtigung pro Empfänger (oder mehrere) pro Plattform handeln.

Jede Benachrichtigung kann plattformspezifische Nutzdaten enthalten (zum Beispiel eine MMS kann einen Ton oder ein Bild enthalten).

Das System muss skalierbar sein. Ich muss in der Lage sein, eine sehr große Menge an Benachrichtigungen zu senden, ohne die Anwendung oder den Server zum Absturz zu bringen.

Es ist ein zweistufiger Prozess. Zuerst kann ein Kunde eine Nachricht eingeben und eine Plattform zum Senden auswählen. Die Benachrichtigung (en) sollten so erstellt werden, dass sie entweder in Echtzeit oder später verarbeitet werden können.

Anschließend muss das System die Benachrichtigung an den Plattformanbieter senden.


Im Moment habe ich zwar einige, aber ich weiß nicht, wie skalierbar es sein wird oder ob es ein gutes Design ist.

Ich habe über folgende Objekte nachgedacht (in einer Pseudosprache):

ein generisches Notification Objekt:

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

Das Problem mit den folgenden Objekten ist, was ist, wenn ich 1.000.000 Empfänger habe? Selbst wenn das Objekt Recipient sehr klein ist, wird zu viel Speicher benötigt.

Ich könnte auch eine Benachrichtigung pro Empfänger erstellen, aber einige Plattformanbieter verlangen, dass ich sie stapelweise sende, was bedeutet, dass ich eine Benachrichtigung mit mehreren Empfängern definieren muss.

Jede erstellte Benachrichtigung kann in einem dauerhaften Speicher wie einer Datenbank oder Redis gespeichert werden.

Wäre es gut, dies später zu aggregieren, um sicherzustellen, dass es skalierbar ist?

Im zweiten Schritt muss ich diese Benachrichtigung verarbeiten.

Aber wie kann ich die Benachrichtigung an den richtigen Plattformanbieter unterscheiden?

Sollte ich ein Objekt wie MMSNotification verwenden, um einen abstract Notification Zu erweitern? oder so etwas wie Notification.setType('MMS')?

Ich denke, ein Messaging-Warteschlangensystem wie RabbitMQ ist möglicherweise das richtige Tool, um viele Benachrichtigungen gleichzeitig verarbeiten zu können. Ist es?

Es würde mir ermöglichen, viele Benachrichtigungen in die Warteschlange zu stellen und mehrere Mitarbeiter zu veranlassen, Benachrichtigungen zu öffnen und zu verarbeiten. Aber was ist, wenn ich die Empfänger wie oben gezeigt stapeln muss?

Dann stelle ich mir ein NotificationProcessor Objekt vor, für das ich NotificationHandler hinzufügen könnte. Jedes NotificationHandler wäre dafür verantwortlich, den Plattformanbieter zu verbinden und eine Benachrichtigung durchzuführen.

Ich kann auch ein EventManager verwenden, um steckbares Verhalten zuzulassen.

Irgendwelche Rückmeldungen oder Ideen?

Vielen Dank für Ihre Zeit.

Hinweis: Ich arbeite gewohnt in PHP und es ist wahrscheinlich die Sprache meiner Wahl.


Bearbeiten (gemäß der Antwort von Morphunreal)

  • Wie viele Nachrichten pro Sekunde senden Sie (Definieren Sie aktuelle/anfängliche Ebenen, definieren Sie eine maximale Ebene, die das System verarbeiten soll, bevor es neu entworfen wird).
  • Welche Hardwareeinschränkungen hat das System (Speicher, CPU usw. stehen dem System zur Verfügung)?
  • Wie skaliert die Hardware (dh Hinzufügen weiterer Server, Cloud Computing usw.)

  • Welche Sprachen/Systeme generieren Benachrichtigungen?

Ich bin selbst dafür verantwortlich, die Benachrichtigung programmgesteuert zu erstellen, aber aus einer Benutzeroberfläche aufgebaut.

  • Kennt der Generator die Empfänger der Nachricht (?) Oder werden sie auf andere Weise bereitgestellt (dh Geschäftsregeln für bestimmte Alarmtypen gehen an bestimmte Empfänger)?

Es sollte möglich sein, eine Benachrichtigung für einen bestimmten Empfänger, eine Gruppe von Empfängern (z. B. mithilfe eines Tag-Systems) oder für eine gesamte Plattform zu erstellen.

  • Gibt es Geschäftsregeln für das Hinzufügen von CC/BCC/Read-Belegen?

Ja. Beachten Sie, dass dies wirklich plattformspezifisch ist und das Lesen oder CC nicht auf allen Plattformen verfügbar ist.

  • Kennt der Generator die Art der Nachricht, die er sendet (z. B. SMS/E-Mail), oder basiert sie auf dem Empfänger?

Es basiert jedoch auf dem Empfänger. Da der Empfänger plattformbezogen ist und Plattformen unterschiedliche Methoden zum Umgang mit Daten haben, ist die Benutzeroberfläche wahrscheinlich plattformspezifisch, um das Einrichten von Bildern, Ton oder Ähnlichem zu ermöglichen.

  • Benötigt der Generator eine Bestätigung der gesendeten/empfangenen/gelesenen Nachrichten (asynchron oder synchrones Senden)?

Nun, das System sollte fehleranfällig sein, aber wir möchten den Fehler behandeln, um einen Regelsatz zu definieren. Wenn beispielsweise der Server nicht erreichbar ist, sollte die Benachrichtigung für den weiteren Prozess angefordert werden, aber wenn die Benachrichtigung falsch ist (oder war) definiert wie vom Plattformanbieter festgelegt) sollte nicht angefordert, sondern benachrichtigt werden.

  • Gibt es Anforderungen zum Speichern eines Verlaufs von Nachrichtenquellen/-empfängern (wie lange?)

Ja, wir möchten wahrscheinlich Statistiken erstellen und Berichte erstellen. * Definieren Sie Benachrichtigungsendpunkte


  • Welche Dienste werden zum Senden von Nachrichten verwendet? Hängt davon ab, einige sind klassisch REST Webservice, andere sind exotische Protokolle, es liegt wirklich am Anbieter.

  • Welches Feedback/welche Bestätigung wird bereitgestellt (synchronisieren/asynchronisieren)

Abhängig davon, dass einige synchron sind und mit einem Fehler antworten, während andere anschließend gezogen werden müssen, um nach Fehlern zu suchen.

  • Ist es wahrscheinlich, dass neue Endpunkte hinzugefügt werden [selbst wenn ja, muss es sogar abstrahiert werden]

Ja, tatsächlich wächst unsere App und wir möchten wahrscheinlich einen neuen Anbieter hinzufügen können, aber es ist ein Verhältnis von ungefähr 1 oder 2 pro Jahr.

33
Trent

Trennen Sie zunächst Ihre funktionalen und nicht funktionalen Anforderungen und definieren Sie sie sorgfältig. Es ist sehr einfach, ein System basierend auf mehrdeutigen Anforderungen zu überarbeiten.

Zum Beispiel sind Ihre nicht funktionalen Anforderungen an die Skalierbarkeit nicht eindeutig. Es kann eine Menge geistiger Belastung entlasten, wenn Sie tatsächliche Zahlen auf Ihr System setzen. Zum Beispiel,

  • Wie viele Nachrichten pro Sekunde senden Sie (Definieren Sie aktuelle/anfängliche Ebenen, definieren Sie eine maximale Ebene, die das System verarbeiten soll, bevor es neu entworfen wird).
  • Welche Hardwareeinschränkungen hat das System (Speicher, CPU usw. stehen dem System zur Verfügung)?
  • Wie skaliert die Hardware (dh Hinzufügen weiterer Server, Cloud Computing usw.)

Nachdem Sie dies aus dem Weg geräumt haben, können Sie einige Tests einrichten sicherstellen, dass das Systemdesign/die Systemarchitektur Ihre nicht funktionalen Anforderungen erfüllen kann.

In Bezug auf die geschäftlichen/funktionalen Anforderungen beim Senden von Benachrichtigungen/Nachrichten können die folgenden Hinweise hilfreich sein (wenn Sie weitere Informationen angeben, die ich dieser Antwort hinzufügen kann):

Benachrichtigungsquellen definieren

  • Welche Sprachen/Systeme generieren Benachrichtigungen?
  • Kennt der Generator die Empfänger der Nachricht (?) Oder werden sie auf andere Weise bereitgestellt (dh Geschäftsregeln für bestimmte Alarmtypen gehen an bestimmte Empfänger)?
  • Gibt es Geschäftsregeln für das Hinzufügen von CC/BCC/Read-Belegen?
  • Kennt der Generator die Art der Nachricht, die er sendet (z. B. SMS/E-Mail), oder basiert sie auf dem Empfänger?
  • Benötigt der Generator eine Bestätigung der gesendeten/empfangenen/gelesenen Nachrichten (asynchron oder synchrones Senden)?
  • Gibt es Anforderungen zum Speichern eines Verlaufs von Nachrichtenquellen/-empfängern (wie lange?)

Benachrichtigungsendpunkte definieren

  • Welche Dienste werden zum Senden von Nachrichten verwendet?
  • Welches Feedback/welche Bestätigung wird bereitgestellt (synchronisieren/asynchronisieren)
  • Ist es wahrscheinlich, dass neue Endpunkte hinzugefügt werden [selbst wenn ja, muss es sogar abstrahiert werden]

Ich zögere, ein konkretes Architekturbeispiel zu liefern, da es stark von den beteiligten Faktoren abhängen würde. Bei den einfachsten Nachrichtensystemen handelt es sich jedoch häufig um eine grundlegende Warteschlange, entweder im Speicher/in der Anwendung, in No-SQL, auf der Festplatte oder in einer relationalen Datenbank. Dann kann ein separater Prozess (oder mehrere separate Prozesse, falls verteilt) die Warteschlange nach ihren Nachrichtentypen abfragen [dh einen Cron-Job]; und nach Bedarf abschicken.

Dies könnte auch mithilfe einiger Push-basierter Techniken (z. B. PostgreSQL NOTIFY/LISTEN) verbessert werden, wenn Nachrichten sofort gesendet werden müssen.

Der Vorteil einer einfachen Warteschlange besteht darin, dass das System, das die Nachricht generiert, wenig Arbeit zu erledigen hat und das Verarbeitungssystem basierend auf den Hardware-/Leistungsanforderungen ausgeglichen werden kann.

16
nathan-m