Come progettare un sistema di notifica scalabile? [chiuso]


32

Devo scrivere un gestore del sistema di notifica.

Ecco i miei requisiti:

Devo essere in grado di inviare una notifica su piattaforme diverse, che potrebbero essere totalmente diverse (ad esempio, devo essere in grado di inviare un SMS o un'e-mail).

A volte la notifica può essere la stessa per tutti i destinatari per una determinata piattaforma, ma a volte può essere una notifica per destinatari (o più) per piattaforma.

Ogni notifica può contenere un payload specifico della piattaforma (ad esempio un MMS può contenere un suono o un'immagine).

Il sistema deve essere scalabile , devo essere in grado di inviare una grande quantità di notifiche senza crash dell'applicazione o del server.

Si tratta di un processo in due fasi, in primo luogo un cliente può digitare un messaggio e scegliere una piattaforma a cui inviare e le notifiche devono essere create per essere elaborate in tempo reale o in un secondo momento.

Quindi il sistema deve inviare la notifica al provider della piattaforma.


Per ora, finisco con alcuni però, ma non so quanto sarà scalabile o se è un buon design.

Ho pensato ai seguenti oggetti (in uno pseudo linguaggio):

un Notificationoggetto generico :

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

Il problema con i seguenti oggetti è cosa succede se ho 1.000.000 di destinatari? Anche se l' Recipientoggetto è molto piccolo, ci vorrà troppa memoria.

Potrei anche creare una notifica per destinatario, ma alcuni provider di piattaforme mi richiedono di inviarla in batch, il che significa che devo definire una notifica con più destinatari.

Ogni notifica creata può essere archiviata in un archivio permanente come un DB o Redis.

Sarebbe positivo aggregarlo successivamente per assicurarsi che sia scalabile?

Nel secondo passaggio, devo elaborare questa notifica.

Ma come potrei distinguere la notifica dal giusto fornitore di piattaforme?

Dovrei usare un oggetto come MMSNotificationestendere un abstract Notification? o qualcosa del genere Notification.setType('MMS')?

Per consentire di elaborare molte notifiche contemporaneamente, penso che un sistema di code di messaggistica come RabbitMQ possa essere lo strumento giusto. È?

Mi consentirebbe di mettere in coda un sacco di notifiche e di avere diversi lavoratori per far apparire le notifiche e elaborarle. Ma cosa succede se devo raggruppare i destinatari come visto sopra?

Quindi immagino che un NotificationProcessoroggetto per il quale potrei aggiungere NotificationHandlerciascuno NotificationHandlersarebbe incaricato di connettere il fornitore della piattaforma ed eseguire la notifica.

Posso anche usare un EventManagerper consentire un comportamento innestabile.

Feedback o idee?

Grazie per aver dedicato il tuo tempo.

Nota: sono abituato a lavorare in PHP ed è probabilmente la lingua che preferisco.


Modifica (secondo la risposta di morfunreal)

  • Quanti messaggi al secondo stai inviando (Definisci i livelli attuali / iniziali, definisci un livello massimo che il sistema dovrebbe gestire prima di essere riprogettato)
  • Quali vincoli hardware ha il sistema (memoria, CPU, ecc. Disponibili per il sistema)
  • Come si ridimensionerà l'hardware (ovvero aggiungendo più server, cloud computing ecc.)

  • Quali lingue / sistemi genereranno notifiche?

È da solo, ho il compito di creare la notifica a livello di codice ma costruita da un'interfaccia utente.

  • Il generatore conosce i destinatari del messaggio (?) O sono forniti con altri mezzi (ad esempio, le regole aziendali per determinati tipi di avviso vanno a determinati destinatari)

Dovrebbe essere possibile creare una notifica per destinatari specifici, un gruppo di destinatari (ad esempio utilizzando un sistema di tag) o per un'intera piattaforma.

  • Esistono regole commerciali per l'aggiunta di ricevute CC / BCC / Read

Sì. Si noti che questo è veramente specifico della piattaforma e la lettura o cc non sono disponibili su tutte le piattaforme.

  • Il generatore conosce il tipo di messaggio che sta inviando (ad es. SMS / e-mail) o è basato sul destinatario?

Si basa sul destinatario, tuttavia, poiché il destinatario è legato alla piattaforma e le piattaforme hanno un modo diverso di gestire i dati, è probabile che l'interfaccia utente sia specifica della piattaforma per consentire l'impostazione di immagini, un suono o qualcosa del genere.

  • Il generatore richiede la conferma dei messaggi inviati / ricevuti / letti (invio asincrono vs sincrono)

Bene, il sistema dovrebbe essere soggetto a errori ma vorremmo gestire l'errore per definire un set di regole, ad esempio, se il server non è raggiungibile, la notifica dovrebbe essere ricodificata per un ulteriore processo, ma se la notifica non è corretta (o è stata definito dal provider della piattaforma) non deve essere rinnovato nella coda ma notificato.

  • Esistono requisiti per memorizzare una cronologia delle origini / destinatari dei messaggi (per quanto tempo?)

Sì, probabilmente vorremmo fare alcune statistiche e riferire. * Definire i punti finali delle notifiche


  • Quali servizi vengono utilizzati per inviare messaggi? Dipende, alcuni sono servizi web REST classici, altri sono protocolli esotici, dipende davvero dal provider.

  • Quale feedback / conferma viene fornito (sync / async)

Dipende, alcuni sono sincroni e rispondono con un errore, mentre altri devono essere estratti per verificare la presenza di errori.

  • È probabile che aggiunga nuovi punti finali [anche se è così, deve anche essere astratto]

Sì, in realtà la nostra app sta crescendo e probabilmente vorremmo poter aggiungere un nuovo provider, ma è un rapporto di qualcosa come 1 o 2 all'anno.


22
Walter, moscerino, gbjbaanb, Robert Harvey, thorsten müller sembrano essere persone pigre; Non vedo alcun motivo per cui questa domanda sia stata chiusa a causa di uno dei seguenti argomenti: "ambiguo, vago, incompleto, eccessivamente ampio o retorico". Una domanda di design non può essere una domanda semplice perché implica moltissime cose, ho pensato che il livello di questo sito Web ha permesso di discutere una decisione così complessa con un vero professionista.
Trento,

Poni domande ma non fare domande! :) Sì, a volte anche io non riesco a capire la mentalità delle mod.
Mrchief,

i voti e le opinioni mostrano quanto questa domanda sia pertinente .... se solo i moderatori avrebbero capito !!!
NoobEditor,

L'uso di RabbitMQ è l'approccio giusto per questo problema. Mi è stato chiesto un problema molto simile in un'intervista della mia GRANDE azienda e stavo lottando con il miglior modello di editore / abbonato tollerante ai guasti. Alla fine mi è stata data la risposta corretta. RabbitMQ. Sembra che abbiano risolto il problema usandolo. Spero che sia d'aiuto!!!
AkD

Risposte:


16

Inizia separando i tuoi requisiti funzionali e non funzionali e definendoli attentamente. È molto facile progettare eccessivamente un sistema basato su requisiti ambigui.

Ad esempio, i requisiti non funzionali in termini di scalabilità sono piuttosto ambigui. Può alleviare un sacco di carico mentale se metti numeri reali sul tuo sistema. Per esempio,

  • Quanti messaggi al secondo stai inviando (Definisci i livelli attuali / iniziali, definisci un livello massimo che il sistema dovrebbe gestire prima di essere riprogettato)
  • Quali vincoli hardware ha il sistema (memoria, CPU, ecc. Disponibili per il sistema)
  • Come si ridimensionerà l'hardware (ovvero aggiungendo più server, cloud computing ecc.)

Ora che lo hai rimosso, puoi impostare alcuni test per garantire che la progettazione / architettura dei sistemi sia in grado di soddisfare i tuoi requisiti non funzionali.

Per quanto riguarda i requisiti aziendali / funzionali di invio di notifiche / messaggi, possono essere utili i seguenti indizi (se si forniscono ulteriori informazioni che posso aggiungere a questa risposta):

Definire le fonti di notifica

  • Quali lingue / sistemi genereranno notifiche
  • Il generatore conosce i destinatari del messaggio (?) O sono forniti con altri mezzi (ad esempio, le regole aziendali per determinati tipi di avviso vanno a determinati destinatari)
  • Esistono regole commerciali per l'aggiunta di ricevute CC / BCC / Read
  • Il generatore conosce il tipo di messaggio che sta inviando (ad es. SMS / e-mail) o è basato sul destinatario?
  • Il generatore richiede la conferma dei messaggi inviati / ricevuti / letti (invio asincrono vs sincrono)
  • Esistono requisiti per memorizzare una cronologia delle origini / destinatari dei messaggi (per quanto tempo?)

Definire i punti finali delle notifiche

  • Quali servizi vengono utilizzati per inviare messaggi
  • Quale feedback / conferma viene fornito (sync / async)
  • È probabile che aggiunga nuovi punti finali [anche se è così, deve anche essere astratto]

Sono titubante nel fornire un esempio concreto di architettura in quanto dipenderebbe pesantemente dalla base dei fattori coinvolti; ma spesso i sistemi di messaggi più semplici comportano una coda di base, in memoria / applicazione, no-SQL, disco o database relazionale. Quindi un processo separato (o più processi separati se distribuiti) può eseguire il polling della coda per i loro tipi di messaggi [cioè un cron job]; e spedire se necessario.

Ciò potrebbe anche essere migliorato utilizzando alcune tecniche basate su push (ad esempio PostgreSQL NOTIFY / LISTEN) se è necessario inviare immediatamente i messaggi.

Il vantaggio di una semplice coda è che il sistema che genera il messaggio ha poco lavoro da fare e il sistema di elaborazione può essere bilanciato in base ai requisiti hardware / prestazionali.


grazie mille per la risposta ai dettagli che in realtà mi aiuta ad avere alcune idee più chiare. Ho modificato la mia risposta per rispondere alle domande che hai sollevato.
Trento,

-2

Hai considerato il modello di progettazione del peso mosca per i tuoi oggetti di notifica? Non ne sono troppo sicuro, dal momento che non ho mai implementato il modello, ma ricordo che comporta la condivisione di uno stato tra gli oggetti flyweight. Penso anche che i membri con più ridondanza abbiano avuto un impatto maggiore se condivisi. Quindi dipende se invii solo pochi messaggi a molte persone o viceversa.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.