web-dev-qa-db-fra.com

Comment concevoir un système de notification évolutif?

J'ai besoin d'écrire un gestionnaire de système de notification.

Voici mes exigences:

Je dois pouvoir envoyer une notification sur différentes plates-formes, qui peuvent être totalement différentes (par exemple, je dois pouvoir envoyer un SMS ou un e-mail).

Parfois, la notification peut être la même pour tous les destinataires pour une plate-forme donnée, mais parfois il peut s'agir d'une notification par destinataire (ou plusieurs) par plate-forme.

Chaque notification peut contenir une charge utile spécifique à la plate-forme (par exemple un MMS peut contenir un son ou une image).

Le système doit être évolutif, je dois être en mesure d'envoyer une très grande quantité de notifications sans planter ni l'application ni le serveur.

Il s'agit d'un processus en deux étapes, tout d'abord un client peut taper un message et choisir une plate-forme vers laquelle envoyer, et la ou les notifications doivent être créées pour être traitées en temps réel ou plus tard.

Ensuite, le système doit envoyer la notification au fournisseur de la plate-forme.


Pour l'instant, je me retrouve avec certains mais je ne sais pas comment il sera évolutif ou si c'est une bonne conception.

J'ai pensé aux objets suivants (dans un pseudo langage):

un objet générique Notification:

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

Le problème avec les objets suivants est que si j'ai 1.000.000 destinataires? Même si l'objet Recipient est très petit, il prendra trop de mémoire.

Je pouvais également créer une notification par destinataire, mais certains fournisseurs de plate-forme m'obligent à l'envoyer par lots, ce qui signifie que je dois définir une notification avec plusieurs destinataires.

Chaque notification créée peut être stockée dans un stockage persistant comme une base de données ou Redis.

Serait-il bon d'agréger cela plus tard pour vous assurer qu'il est évolutif?

À la deuxième étape, je dois traiter cette notification.

Mais comment distinguer la notification au bon fournisseur de plateforme?

Dois-je utiliser un objet comme MMSNotification étendant un abstract Notification? ou quelque chose comme Notification.setType('MMS')?

Pour permettre de traiter beaucoup de notifications en même temps, je pense qu'un système de file d'attente de messagerie comme RabbitMQ peut être le bon outil. C'est ça?

Cela me permettrait de mettre en file d'attente beaucoup de notifications et de demander à plusieurs travailleurs de les afficher et de les traiter. Mais que faire si j'ai besoin de regrouper les destinataires comme indiqué ci-dessus?

Ensuite, j'imagine qu'un NotificationProcessor objet auquel je pourrais ajouter NotificationHandler chaque NotificationHandler serait chargé de connecter le fournisseur de la plateforme et d'effectuer une notification.

Je peux également utiliser un EventManager pour permettre un comportement enfichable.

Des retours ou des idées?

Merci d'avoir donné de votre temps.

Remarque: J'ai l'habitude de travailler en PHP et c'est probablement la langue de mon choix.


Modifier (selon la réponse de morphunreal)

  • Combien de messages par seconde envoyez-vous (Définissez les niveaux actuels/initiaux, définissez un niveau maximum que le système doit gérer avant d'être repensé)
  • De quelles contraintes matérielles le système dispose-t-il (mémoire, cpu, etc. disponibles pour le système)
  • Comment le matériel évoluera-t-il (c'est-à-dire en ajoutant plus de serveurs, le cloud computing, etc.)

  • Quels langages/systèmes vont générer des notifications?

C'est par moi-même, je suis en charge de créer la notification par programmation mais construite à partir d'une interface utilisateur.

  • Le générateur connaît-il les destinataires du message (?) Ou sont-ils fournis par d'autres moyens (c'est-à-dire que les règles métier pour certains types d'alerte vont à certains destinataires)

Il devrait être possible de créer une notification pour des destinataires spécifiques, un groupe de destinataires (par exemple à l'aide d'un système de balises) ou pour une plate-forme entière.

  • Existe-t-il des règles commerciales pour ajouter des reçus CC/BCC/Lire

Oui. Notez que cela est vraiment spécifique à la plate-forme et la lecture ou le cc ne sont pas disponibles sur toutes les plates-formes.

  • Le générateur sait-il le type de message qu'il envoie (par exemple, SMS/e-mail) ou est-il basé sur le destinataire

Il est basé sur le destinataire, cependant, comme le destinataire est lié à la plate-forme et que les plates-formes ont une manière différente de gérer les données, l'interface utilisateur est susceptible d'être spécifique à la plate-forme pour permettre de configurer des images, un son ou quelque chose.

  • Le générateur nécessite-t-il une confirmation des messages envoyés/reçus/lus (envoi asynchrone ou synchrone)

Eh bien, le système devrait être sujet aux erreurs, mais nous aimerions traiter l'erreur pour définir un ensemble de règles, par exemple, si le serveur est inaccessible, la notification doit être remise en file d'attente pour un processus ultérieur, mais si la notification est incorrecte (ou a été défini par le fournisseur de la plate-forme), il ne doit pas être remis en file d'attente mais notifié.

  • Y a-t-il des exigences pour stocker un historique des sources/destinataires des messages (combien de temps?)

Oui, nous voulons probablement faire des statistiques et faire un rapport. * Définir les points de fin de notification


  • Quels services sont utilisés pour envoyer des messages? Cela dépend, certains sont classiques REST webservice, d'autres sont des protocoles exotiques, c'est vraiment au fournisseur.

  • Quels commentaires/confirmations sont fournis (synchronisation/async)

Cela dépend, certains sont synchrones et répondent avec une erreur tandis que d'autres doivent être extraits par la suite pour vérifier les erreurs.

  • Est-il susceptible d'ajouter de nouveaux points d'extrémité [même si c'est le cas, doit-il même être résumé]

Oui, en fait, notre application se développe et nous souhaitons probablement pouvoir ajouter un nouveau fournisseur, mais c'est un ratio de quelque chose comme 1 ou 2 par an.

33
Trent

Commencez par séparer vos exigences fonctionnelles et non fonctionnelles et définissez-les soigneusement. Il est très facile de sur-concevoir un système en fonction d'exigences ambiguës.

Par exemple, vos exigences non fonctionnelles en matière d'évolutivité sont assez ambiguës. Cela peut soulager beaucoup de charge mentale si vous mettez des chiffres réels sur votre système. Par exemple,

  • Combien de messages par seconde envoyez-vous (Définissez les niveaux actuels/initiaux, définissez un niveau maximum que le système doit gérer avant d'être repensé)
  • De quelles contraintes matérielles le système dispose-t-il (mémoire, cpu, etc. disponibles pour le système)
  • Comment le matériel évoluera-t-il (c'est-à-dire en ajoutant plus de serveurs, le cloud computing, etc.)

Maintenant que vous n'avez plus rien à faire, vous pouvez mettre en place des tests pour vous assurer que la conception/architecture des systèmes est capable de répondre à vos exigences non fonctionnelles.

En ce qui concerne les exigences commerciales/fonctionnelles de l'envoi de notifications/messages, les indices suivants peuvent aider (si vous fournissez plus d'informations, je peux ajouter à cette réponse):

Définir les sources de notification

  • Quels langages/systèmes vont générer des notifications
  • Le générateur connaît-il les destinataires du message (?) Ou sont-ils fournis par d'autres moyens (c'est-à-dire que les règles métier pour certains types d'alerte vont à certains destinataires)
  • Existe-t-il des règles commerciales pour ajouter des reçus CC/BCC/Lire
  • Le générateur sait-il le type de message qu'il envoie (par exemple, SMS/e-mail) ou est-il basé sur le destinataire
  • Le générateur nécessite-t-il une confirmation des messages envoyés/reçus/lus (envoi asynchrone ou synchrone)
  • Y a-t-il des exigences pour stocker un historique des sources/destinataires des messages (combien de temps?)

Définir les points finaux de notification

  • Quels services sont utilisés pour envoyer des messages
  • Quels commentaires/confirmations sont fournis (synchronisation/async)
  • Est-il susceptible d'ajouter de nouveaux points d'extrémité [même si c'est le cas, doit-il même être résumé]

J'hésite à fournir un exemple d'architecture concrète car cela dépendrait fortement des facteurs impliqués; mais souvent, les systèmes de messagerie les plus simples impliquent une file d'attente de base, soit dans la mémoire/application, pas de SQL, sur disque ou dans une base de données relationnelle. Ensuite, un processus distinct (ou plusieurs processus distincts s'ils sont distribués) peut interroger la file d'attente pour leurs types de messages [c'est-à-dire un travail cron]; et envoyer si nécessaire.

Cela pourrait également être amélioré en utilisant certaines techniques basées sur Push (par exemple PostgreSQL NOTIFY/LISTEN) s'il est nécessaire d'envoyer des messages immédiatement.

L'avantage d'une simple file d'attente est que le système générant le message a peu de travail à faire et que le système de traitement peut être équilibré en fonction des exigences matérielles/de performances.

16
nathan-m