Architettura per la tecnologia basata su accodamento in un ambiente Micro-Service e multi-tenant

1

Si spera che il titolo non sia dolorosamente oscuro, ma come indica, sono davvero alla ricerca di consigli sulla mia proposta di architettura, poiché l'architettura attuale è soggetta a problemi di concorrenza, problemi di prestazioni e dettata da software di terze parti.

La piattaforma è essenzialmente un pattern Micro-Service ingenuo seguito dall'accesso in modalità Multi-Tenant.

Abbiamo un'API di base che inserisce i dati principali, ma i dati principali devono essere complimentati da altri dati, in questo esempio: Assets , C1 e C2 .

Ora l'idea è di inserire i dati di base, quindi pubblicare in una coda, ogni modulo deve essere sottoscritto, complimentare i dati e quindi pubblicare nuovamente nella coda, che viene quindi sottoscritta tramite gli altri moduli in sequenza. A quel punto tutti i dati sono complimentati dando un set completo di dati, che poi viene infine sottoscritto tramite l'ultimo modulo, che poi fa un po 'di magia super-uber e restituito.

Ci aspettiamo un volume di migliaia di richieste e probabilmente milioni a tempo debito. Le prestazioni / velocità sono assolutamente vitali ma più prestazioni. Limitazione dei timeout e del tempo di attesa, è anche vitale e può essere raggiunta tramite attività parallele / in background. È il volume di throughput che ha la priorità più alta.

Domande:

  1. Questa architettura è fattibile?
  2. La tecnologia basata su accodamento può / può contenere la capacità di pubblicare, sottoscrivere gli stessi dati in modo sequenziale fino a quando tali dati sono ritenuti completi? ogni volta che riceviamo i dati complimentare i dati e respingere pubblicando
posta Tez Wingfield 07.03.2018 - 15:28
fonte

2 risposte

1

Le soluzioni basate su Coda distribuita presentano una serie di vantaggi per i sistemi asincroni, specialmente quando sono focalizzati sulla velocità effettiva. Non consiglierei l'uso di code distribuite come parte delle transazioni sincrone.

Pro

  • Il volume può essere livellato. L'elaborazione continuerà alla velocità massima e l'overflow verrà gestito sulle code.
  • Se progettato correttamente, il ridimensionamento è facile. Basta aggiungere nuovi nodi di elaborazione per prelevare dalle code.
  • I tempi di inattività sull'elaborazione dei nodi non impediscono (generalmente) che nuove richieste vengano accettate.

Contro

  • Le code richiedono memoria e / o disco. Se è necessario conservare i messaggi quando l'accodamento è inattivo, è necessario scrivere ciascun messaggio sul disco. Il sovraccarico dell'IO può essere significativo.
  • A seconda della tecnologia, devi prendere molte decisioni in anticipo come la profondità che sosterrai in una coda e quanto possono essere grandi i messaggi.
  • I sistemi di accodamento con cui ho lavorato non gestiscono i messaggi di grandi dimensioni in modo efficiente. Ci sono soluzioni alternative ma possono essere complicate.
  • Può essere difficile trovare persone con esperienza nella progettazione e nello sviluppo di queste soluzioni e anche persone che sanno come supportare l'infrastruttura.
  • A differenza di una lettura su un database, ottenere una coda è distruttivo. È facile per gli sviluppatori impegnare i messaggi in anticipo con conseguente perdita di dati.

Non posso esagerare con l'ultimo con: ci sono così tanti modi in cui i messaggi possono essere persi nello shuffle e può essere molto difficile scoprire che sta accadendo. Per questo motivo, ti consiglio vivamente di tenere un registro delle transazioni che registra almeno ogni richiesta che arriva ed è lo stato finale. L'altra cosa da considerare è che alcuni sistemi di accodamento popolari hanno alcuni difetti profondi. Ad esempio, un sistema che ho usato controlla ogni messaggio in una coda ogni volta che tenti di leggere il messaggio successivo. Ciò significa che se si rimane indietro sull'elaborazione dei messaggi, ogni lettura diventa più lenta e più lenta, con il risultato di una spirale al ribasso del peggioramento delle prestazioni. Caveat emptor. Ho anche lavorato con strane configurazioni che fanno funzionare una coda come una pila che ha creato risultati davvero indesiderati sotto carico pesante.

Il tuo design

Questo sembra un approccio piuttosto tipico basato sulla coda. Hai dei messaggi che arrivano dalla porta principale e li passi lungo una soluzione di assemblaggio.

Ciò che non è chiaro dal tuo diagramma è se avrai code più o meno letteralmente pianificando di "spingere indietro" nella stessa coda di cui ogni passo legge. Se si prevede di utilizzare una singola coda, non farlo! Consiglio vivamente di utilizzare una coda separata per ogni fase del processo, come nel diagramma seguente:

Puoi farlo funzionare con una coda ma non essere elegante. Creerai solo una serie di problemi che non è necessario che esistano. Inoltre, rende molto più difficile il supporto. Con le code separate, puoi vedere in un istante dove sei in ritardo: la coda con profondità diversa da zero viene scritta più velocemente di quanto viene letta da. E questo è l'ultimo punto su cui ho visto persone con cui lottare. A lungo termine, i tuoi approfondimenti dovrebbero andare tutti a zero. Se hai code che stanno crescendo nel tempo, stai andando incontro ai problemi.

Un altro ritengo che raccomando che non si tratti rigorosamente di fare la coda. Evita gli aggiornamenti ai record nel DB nei tuoi processi. Usa solo inserti. L'aggiornamento dei record creerà contesa tra i nodi di elaborazione e renderà meno efficace il ridimensionamento della soluzione.

    
risposta data 07.03.2018 - 18:10
fonte
0

Can queuing based technology have/contain the ability to publish, subscribe the same data sequentially until that data is deemed complete?

Una coda non dovrebbe essere un database. Sono sicuro che in qualche modo puoi incidere le code per farlo funzionare, ma perché farlo.

L'approccio più semplice sarebbe quello di creare una singola coda di messaggi e postare ogni elemento di lavoro in entrata in essa. Un processo in background prende da quella coda, chiama in Risorse, C1 e C2 (possibilmente in parallelo), combina i dati e infine invoca il modulo magico con i dati combinati.

Se si desidera che ciascuna delle risorse, C1 e C2 gestite da una coda di messaggi separata, il processo potrebbe essere simile a questo:

È possibile tenere traccia di ogni elemento di lavoro come una riga del database. Quindi si crea una coda di messaggi per ogni risorsa, C1 e C2. Pubblichi l'ID di quella riga di database a quelle code. I rispettivi servizi raccoglieranno il messaggio in coda per fornire dati e archiviarli nella riga del database.

Ogni servizio rileverebbe se la riga è stata riempita completamente (o se si è verificato un errore e il processo deve essere abbandonato). Quando tutto il lavoro è completato, in qualche modo si attiva il modulo magico (possibilmente accodando in un'altra coda di messaggi creata per questo scopo).

Se vuoi che le risorse, C1 e C2 sappiano dell'esistenza della riga di database centrale che monitora il lavoro, devi invertire il controllo. Ciascuna delle risorse, C1 e C2 invierebbe un messaggio in coda ad un servizio del controller centrale per notificare che il proprio lavoro è stato completato. Il controller centrale controllerebbe se il lavoro all è terminato e se così è, invoca il modulo magico.

Voglio consigliarti di scegliere l'architettura più semplice che funzionerà. È molto facile creare elaborati flussi di dati in coda e applicare "modelli di nuvole" sulla lavagna bianca. Implementare, testare e eseguire tutto questo è molto lavoro. Sistemi come questo possono essere molto fragili.

    
risposta data 07.03.2018 - 16:50
fonte

Leggi altre domande sui tag