broker AMQP e garanzie di successo

2

Sto cercando di capire come un broker AMQP, come RabbitMQ, può essere integrato nella nostra architettura. Questo dovrebbe consentire di scalare facilmente in orizzontale in futuro.

Per semplicità, permettimi di porre la domanda tramite un'analogia.

Dì che hai:

  • Un insieme di conti bancari . Supponiamo che il numero di account possa aumentare e diminuire in qualsiasi momento.
  • Un pool fisso di lavoratori / consumatori . Questi lavoratori sono responsabili dell'esecuzione di azioni su un conto bancario, come un prelievo.
  • Un'interfaccia utente , che offre all'utente la possibilità di avviare un'azione, ad esempio un prelievo.
  • Uno scambio AMQP .

Quando l'utente avvia un prelievo, un messaggio che incapsula questa azione è dato allo scambio AMQP. Lo scambio mette il messaggio in una coda, e verrà raccolto da uno dei lavoratori disponibili che consumano questa coda.

Ma cosa succede se l'utente "immediatamente" avvia un altro prelievo? Il messaggio corrispondente potrebbe essere prelevato da un altro lavoratore, con il risultato che due lavoratori elaborano contemporaneamente lo stesso conto bancario.

Come ci si sincronizza tra i lavoratori per garantire una relazione prima dell'evento? Come prevedi che un lavoratore stia lavorando sullo stesso conto bancario e poi su un altro?

Dato che sono abbastanza nuovo per la progettazione architettonica, questa potrebbe essere una domanda generica. Sono felice di qualsiasi risorsa esterna utile (libro, ...) che potrebbe aiutarmi qui.

    
posta Jef Jedrison 24.06.2016 - 11:29
fonte

2 risposte

1

Quindi, hai due problemi qui

1: Prevenire / Risolvere Azioni simultanee (prelievi) su una singola risorsa (conto bancario)

2: applica le azioni di elaborazione (prelievi) in un ordine particolare

Nel tuo esempio, potresti risolvere 1 in vari modi, ma lascia che sia il più semplice. L'elaborazione del prelievo chiama ReduceBalance (accountId, importo) su un servizio di un conto bancario che elabora le richieste in modo sincrono.

Non ti importa quale ritiro avviene per primo, perché qualsiasi cosa succederà per errore a causa della mancanza di equilibrio

La risoluzione di 2 è più complessa, diciamo che c'è qualche logica aziendale nell'ordine in cui i prelievi devono aver luogo. Quelli dall'account X che si verificano nella stessa finestra temporale di alcuni dall'account Y devono avvenire per primi.

Per prima cosa devi determinare l'ordine applicando questa logica che implica una qualche forma di comunicazione tra i lavoratori. Penso che questo sia il modo migliore per ottenere un processo MasterWorker (MW) il cui unico compito è gestire i vari processi di lavoro (WP) e indirizzare i lavori alle loro code.

  1. WP - > contatta MW e registra la disponibilità per il lavoro
  2. MW - > estrae il lavoro dalla coda e applica la logica di ordinazione (in questo caso creare una raccolta di lavori che si verificano in una casella di tempo e ordinarli. questo può essere fatto spostandoli su una coda di attesa)
  3. MW - > inviare prima i lavori ordinati a un WP e associare quel WP alla coda dei lavori ordinati (ad esempio, ricordare chi sta lavorando su di essi)
  4. WP - > processo di lavoro
  5. WP - > invia un messaggio di lavoro completo a MW e registra nuovamente il lavoro
  6. MW - > perché ricordo che il WP che ho assegnato a quel lavoro so che è completo e il secondo lavoro diventa processabile
  7. MW - > invia lavoro 2 a un WP ....

Tutti i vari messaggi e stati possono essere completati tramite le code e l'elaborazione asincrona distribuita è ancora possibile, ovvero è possibile avere contemporaneamente più gruppi di messaggi in movimento. L'unico problema è assicurarti che hai solo un MW in esecuzione alla volta. Rabbit MQ ha un metodo di blocco esclusivo su una coda che può essere usato, ma a mio avviso è un po 'instabile.

    
risposta data 24.06.2016 - 13:19
fonte
0

Potrebbe esserci un'altra soluzione oltre a quella proposta da Ewan, sebbene la sua sia eccellente. Supponiamo che tu abbia un gruppo di code. In qualsiasi momento, una coda è libera (non utilizzata affatto) o assegnata a un conto bancario specifico.

Hai ancora bisogno di un operatore principale per allocare una coda da utilizzare, assegnarla a un conto bancario e renderla disponibile al successivo lavoratore subordinato libero.

Supponiamo ora di disporre di un meccanismo per garantire che un lavoratore che estrae un elemento di lavoro da una coda, utilizzi un meccanismo di sincronizzazione per garantire che nessun altro lavoratore possa accedere a tale coda mentre l'elemento di lavoro viene elaborato. Dopo l'elaborazione dell'elemento di lavoro, la coda viene rilasciata per essere utilizzata da qualsiasi operatore.

La coda rimane assegnata a un conto bancario finché non è vuota. Diventa quindi gratuito e torna al pool di code gratuito.

Questo è molto simile alla soluzione proposta da Ewan. La differenza principale è che dovrai allocare più code e potresti avere meno dipendenti.

    
risposta data 24.06.2016 - 18:18
fonte