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)
C'est par moi-même, je suis en charge de créer la notification par programmation mais construite à partir d'une interface utilisateur.
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.
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.
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.
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é.
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.
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.
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,
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
Définir les points finaux de notification
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.