Architettura per applicazioni in tempo reale, evitando messaggi duplicati per code senza utenti attivi

3

Sto progettando l'architettura di un'applicazione che ha i tipici componenti back-end e front-end. L'applicazione di frontend deve essere semi-in tempo reale. Per questo requisito, il backend sta spingendo i messaggi su una coda e il frontend sta consumando quella coda. Molto probabilmente, userò RabbitMQ per questo. Lasciami spiegare.

Quando l'utente è connesso all'applicazione frontend, viene creata una sessione nel back-end. Finché questa sessione è valida, l'applicazione frontend può operare. In genere, dopo il log-in, il frontend carica inizialmente tutti i dati da un'API REST (con la sua sessione come credenziali di autenticazione) e tutti gli aggiornamenti successivi verranno ricevuti tramite la coda dei messaggi.

Nel mio attuale design, ogni sessione di frontend ha la sua coda. Quindi ogni volta che qualcosa cambia nel back-end, un messaggio viene inviato a tutte le code di sessione rilevanti. Come detto, il frontend sta consumando questa coda.

Il problema è quando il frontend è disconnesso dalla coda. Ad esempio, quando l'utente mette in letargo il suo laptop alla fine della sua giornata lavorativa. Da quel momento in poi, i messaggi inizieranno ad accumularsi. Il vero problema è che la coda viene popolata con messaggi duplicati. Più a lungo il client viene disconnesso dalla coda, più grande diventa questo problema.

Piccola nota a margine, con duplicate messages I in realtà significa semantically identical messages . Prendiamo ad esempio una domanda di borsa. Due messaggi di price of stock xyz has been changed sono semanticamente identici. Provengono da un altro evento / transazione, ma definiscono lo stesso cambiamento. Quindi, il messaggio precedente è diventato obsoleto da quello nuovo. Vedi i commenti per maggiori dettagli.

Sto cercando un'architettura per risolvere questo problema. Lasciami andare oltre i miei pensieri:

  • Invece di avere un session queue , avrei potuto creare un session exchange . Dopo il log-in, è possibile effettuare una coda privata di eliminazione automatica dedicata che è associata a tale scambio. Dopo la disconnessione / timeout, questa coda verrà cancellata dal broker. Quindi, quando l'applicazione di frontend ritorna, verrà creata una nuova coda. In altre parole, l'applicazione di frontend ritorna con una coda vuota.

    • Ma questo costringe il client ad aggiornare tutti i dati dopo una riconnessione. Tutto avrebbe potuto essere cambiato.
    • Vorrei mantenere il cliente il più stupido / semplice possibile
    • Pertanto, ritengo che questa non sia una soluzione ottimale.
  • Quindi, avrebbe senso risolvere questo nel backend. In altre parole, ho bisogno di un modo per prevenire messaggi duplicati nelle code di sessione. Se un certo messaggio è già in coda, non accoderò più lo stesso messaggio.

    • Quali sono le mie opzioni qui? Come faccio a sapere che un certo messaggio è già in coda? Capisco perfettamente che questo non è direttamente supportato da AMQP. Quindi, per implementarlo da solo, credo che questo significhi che dovrei essere in grado di tenere traccia della consegna dei messaggi e idealmente anche sui riconoscimenti dei messaggi. È possibile?
    • Un altro percorso potrebbe essere quello di renderci delle funzioni TTL, lettera morta, ... del broker MQ (Rabit). Tuttavia, non ho potuto trovare qualcosa che funzioni davvero.

La mia domanda si riduce a questo: come posso aggiornare il client dopo una disconnessione?

Qualsiasi idea o intuizione è molto gradita.

    
posta TheMQJuggler 28.06.2017 - 09:57
fonte

1 risposta

1

Non sono sicuro di vedere i valori delle code qui, una comunicazione bidrectionnal diretta sarebbe meglio e risolverebbe il tuo problema attuale, quando l'utente tornerà dal letargo dei suoi computer, dovrà aggiornare completamente la sua pagina per attivarsi indietro la comunicazione bidrectionnal.

Se usi un'applicazione Web, cerca STOMP / Web Socket, se non lo fai, puoi ancora usare STOMP e Web Socket, ma una semplice connessione TCP potrebbe fare anche il lavoro.

Si noti che sono librerie per fornire una connessione TCP molto affidabile con auto-riconnettersi e così via per gestire i problemi di rete che non vanno a codificarli di nuovo, queste cose sono davvero difficili da sviluppare e testare correttamente.

Altri modi:

  • Invece di consegnare i messaggi uno alla volta al client, consegnare tutto quando sono più di uno, tradurli in un Set (raccolta di oggetti unici) di azioni da eseguire ed eseguire tutte le azioni.
  • Perché la sessione dell'utente non scade dopo 30 minuti di inattività? Quando scade, pulisci la coda.
  • RabbitMQ non implementa la specifica JMS, quindi potrebbe non avere un equivalente di JMS Topic con abbonamenti durevoli, che sembra adattarsi meglio del tuo sistema.
risposta data 28.06.2017 - 10:23
fonte