Necesito escribir un administrador del sistema de notificaciones.
Aquí están mis requisitos:
Necesito poder enviar una Notificación en diferentes plataformas, lo que puede ser totalmente diferente (por ejemplo, necesito poder enviar un SMS o un Correo electrónico).
A veces, la notificación puede ser la misma para todos los destinatarios de una plataforma determinada, pero a veces puede ser una notificación por destinatario (o varios) por plataforma.
Cada notificación puede contener una carga útil específica de la plataforma (por ejemplo, una lata MMS contiene un sonido o una imagen).
El sistema debe ser escalable , necesito poder enviar una gran cantidad de notificaciones sin que se bloquee ni la aplicación ni el servidor.
Es un proceso de dos pasos, primero un cliente puede escribir un mensaje y elegir una plataforma para enviar, y las notificaciones deben crearse para ser procesadas en tiempo real o más tarde.
Luego, el sistema debe enviar la notificación al proveedor de la plataforma.
Por ahora, termino con algunos, pero no sé cuán escalable será o si es un buen diseño.
He pensado en los siguientes objetos (en un pseudo lenguaje):
un Notification
objeto genérico :
class Notification {
String $message;
Payload $payload;
Collection<Recipient> $recipients;
}
El problema con los siguientes objetos es ¿qué pasa si tengo 1,000,000 de destinatarios? Incluso si el Recipient
objeto es muy pequeño, tomará demasiada memoria.
También podría crear una Notificación por destinatario, pero algunos proveedores de plataformas requieren que lo envíe por lotes, lo que significa que necesito definir una Notificación con varios Destinatarios.
Cada notificación creada podría almacenarse en un almacenamiento persistente como un DB o Redis.
¿Sería bueno agregar esto más tarde para asegurarse de que sea escalable?
En el segundo paso, necesito procesar esta notificación.
Pero, ¿cómo podría distinguir la notificación al proveedor de plataforma correcto?
¿Debo usar un objeto como MMSNotification
extender un abstract Notification
? o algo asi Notification.setType('MMS')
?
Para permitir procesar muchas notificaciones al mismo tiempo, creo que un sistema de cola de mensajes como RabbitMQ puede ser la herramienta adecuada. ¿Lo es?
Me permitiría poner en cola muchas notificaciones y tener a varios trabajadores para hacer estallar notificaciones y procesarlas. Pero, ¿qué sucede si necesito agrupar a los destinatarios como se ve arriba?
Luego imagino que un NotificationProcessor
objeto para el que podría agregar NotificationHandler
cada uno NotificationHandler
se encargaría de conectar al proveedor de la plataforma y realizar la notificación.
También puedo usar un EventManager
para permitir un comportamiento conectable.
¿Alguna retroalimentación o ideas?
Gracias por darme tu tiempo.
Nota: Estoy acostumbrado a trabajar en PHP y es probable que sea el idioma de mi elección.
Editar (según la respuesta de morphunreal)
- Cuántos mensajes por segundo está enviando (defina los niveles actuales / iniciales, defina un nivel máximo que el sistema debe manejar antes de ser rediseñado)
- Qué restricciones de hardware tiene el sistema (memoria, CPU, etc. disponibles para el sistema)
- Cómo escalará el hardware (es decir, agregar más servidores, computación en la nube, etc.)
- ¿Qué lenguajes / sistemas generarán notificaciones?
Es por mi cuenta, estoy a cargo de crear la notificación mediante programación pero construida a partir de una interfaz de usuario.
- ¿El generador conoce a los destinatarios del mensaje (?) O se los proporciona por algún otro medio (es decir, las reglas comerciales para ciertos tipos de alertas van a ciertos destinatarios)
Debería ser posible crear una notificación para destinatarios específicos, un grupo de destinatarios (por ejemplo, utilizando un sistema de etiquetas) o para toda una plataforma.
- ¿Existen reglas comerciales para agregar recibos CC / BCC / Read
Sí. Tenga en cuenta que esto es realmente específico de la plataforma y la lectura o cc no están disponibles en todas las plataformas.
- ¿Sabe el generador el tipo de mensaje que está enviando (es decir, SMS / correo electrónico) o se basa en el destinatario?
Sin embargo, se basa en el destinatario, ya que el destinatario está relacionado con la plataforma y las plataformas tienen una forma diferente de manejar los datos, es probable que la IU sea específica de la plataforma para permitir la configuración de imágenes, un sonido o algo así.
- ¿Requiere el generador la confirmación de los mensajes que se envían / reciben / leen (envío asíncrono vs síncrono)
Bueno, el sistema debería ser propenso a errores, pero nos gustaría manejar el error para definir un conjunto de reglas, por ejemplo, si el servidor no es accesible, la notificación debe solicitarse para un proceso posterior, pero si la notificación es incorrecta (o ha sido definido como es por el proveedor de la plataforma) no debe ser solicitado sino notificado.
- ¿Hay requisitos para almacenar un historial de fuentes / destinatarios de mensajes (¿por cuánto tiempo?)
Sí, es probable que queramos hacer algunas estadísticas e informes. * Definir puntos finales de notificación
¿Qué servicios se utilizan para enviar mensajes? Depende, algunos son servicios web REST clásicos, otros son protocolos exóticos, realmente depende del proveedor.
Qué comentarios / confirmación se proporcionan (sincronización / asíncrono)
Depende, algunos son síncronos y responden con un error, mientras que otros deben extraerse después para verificar si hay errores.
- ¿Es probable que agregue nuevos puntos finales [incluso si es así, incluso necesita ser abstraído]
Sí, en realidad, nuestra aplicación está creciendo y es probable que queramos agregar un nuevo proveedor, pero es una proporción de 1 o 2 por año.
Respuestas:
Comience separando sus requisitos funcionales y no funcionales y definiéndolos cuidadosamente. Es muy fácil sobre-diseñar un sistema basado en requisitos ambiguos.
Por ejemplo, sus requisitos no funcionales con respecto a la escalabilidad son bastante ambiguos. Puede aliviar mucha carga mental si coloca números reales en su sistema. Por ejemplo,
Ahora que tiene eso fuera del camino, puede configurar algunas pruebas para asegurarse de que el diseño / arquitectura de los sistemas sea capaz de cumplir con sus requisitos no funcionales.
En cuanto a los requisitos comerciales / funcionales de enviar notificaciones / mensajes, las siguientes pistas pueden ayudar (si proporciona más información, puedo agregar a esta respuesta):
Definir fuentes de notificación
Definir puntos finales de notificación
Dudo en proporcionar un ejemplo de arquitectura concreta, ya que dependería en gran medida de los factores involucrados; pero a menudo los sistemas de mensajes más simples implican una cola básica, ya sea en memoria / aplicación, no SQL, disco o base de datos relacional. Luego, un proceso separado (o varios procesos separados si se distribuyen) puede sondear la cola para sus tipos de mensajes [es decir, un trabajo cron]; y enviar según sea necesario.
Esto también podría mejorarse utilizando algunas técnicas basadas en inserción (es decir, NOTIFICAR / ESCUCHAR PostgreSQL) si existe el requisito de que los mensajes se envíen de inmediato.
La ventaja de una cola simple es que el sistema que genera el mensaje tiene poco trabajo por hacer y el sistema de procesamiento puede equilibrarse en función de los requisitos de hardware / rendimiento.
fuente
¿Ha considerado el patrón de diseño de peso mosca para sus objetos de notificación? No estoy muy seguro al respecto, ya que nunca implementé el patrón, pero recuerdo que implica compartir algún estado entre los objetos de peso mosca. También creo que los miembros con más redundancia tuvieron un mayor impacto si se compartían. Por lo tanto, depende si envía solo unos pocos mensajes a mucha gente o viceversa.
fuente