Mönster för sekventiell konvoj

Bearbeta en uppsättning relaterade meddelanden i en definierad ordning, utan att blockera bearbetningen av andra grupper av meddelanden.

Kontext och problem

Program behöver ofta bearbeta en sekvens med meddelanden i den ordning de tas emot, samtidigt som de kan skalas ut för att hantera ökad belastning. I en distribuerad arkitektur är det inte enkelt att bearbeta dessa meddelanden i ordning, eftersom arbetarna kan skala oberoende och ofta hämta meddelanden oberoende av varandra med hjälp av mönstret Konkurrerande konsumenter.

Till exempel tar ett orderspårningssystem emot ett redovisningsregister som innehåller ordrar och relevanta åtgärder för dessa beställningar. Dessa åtgärder kan vara att skapa en order, lägga till en transaktion i ordern, ändra en tidigare transaktion eller ta bort en order. I det här systemet måste åtgärder utföras på fifo-sätt (först in först ut), men bara på ordernivå. Den första kön tar dock emot ett transaktionsregister som innehåller transaktioner för många beställningar, som kan interleaveras.

Lösning

Skicka relaterade meddelanden till kategorier i kösystemet och lås kölyssnare och hämta endast från en kategori, ett meddelande i taget.

Så här ser det allmänna mönstret för sekventiell konvoj ut:

Diagram över mönster för sekventiell konvoj

I kön kan meddelanden för olika kategorier interparas, som du ser i följande diagram:

Diagram som visar överflätade meddelanden

Problem och överväganden

Tänk på följande när du bestämmer hur du ska implementera mönstret:

  • Kategori/skalningsenhet. Vilken egenskap för dina inkommande meddelanden kan du skala ut på? I orderspårningsscenariot är den här egenskapen order-ID:t.
  • Genomströmning. Vilket dataflöde har målmeddelandet? Om den är mycket hög kan du behöva fundera över dina FIFO-krav. Kan du till exempel framtvinga ett start-/slutmeddelande, sortera efter tid och sedan skicka en batch för bearbetning?
  • Tjänstfunktioner. Tillåter ditt val av meddelandebuss bearbetning av meddelanden i en kö eller kategori i en kö en gång i taget?
  • Föränderlighet. Hur lägger du till en ny meddelandekategori i systemet? Anta till exempel att huvudboken som beskrivs ovan är specifik för en kund. Om du behövde registrera en ny kund, kan du ha en uppsättning redovisningsprocessorer som distribuerar arbete per kund-ID?
  • Det är möjligt att konsumenter får ett meddelande i ordningsföljd på grund av varierande nätverksfördröjning när meddelanden skickas. Överväg att använda sekvensnummer för att verifiera ordningen. Du kan också inkludera en särskild "sekvensslutsflagga" i det sista meddelandet i en transaktion. Dataströmbearbetningstekniker som Spark eller Azure Stream Analytics kan bearbeta meddelanden i ordning inom en tidsperiod.

När du ska använda det här mönstret

Använd det här mönstret i sådana här scenarier:

  • Du har meddelanden som tas emot i ordning och som måste bearbetas i samma ordning.
  • Inkommande meddelanden är eller kan "kategoriseras" på ett sådant sätt att kategorin blir en skalningsenhet för systemet.

Det här mönstret är kanske inte lämpligt för:

  • Extremt höga dataflödesscenarier (miljontals meddelanden per minut eller sekund), eftersom FIFO-kravet begränsar den skalning som kan göras av systemet.

Exempel

I Azure kan det här mönstret implementeras med hjälp av Azure Service Bus-meddelandesessioner. För konsumenter kan du använda antingen Logic Apps med Service Bus peek-lock-anslutning eller Azure Functions med Service Bus utlösaren.

I föregående orderspårningsexempel bearbetar du varje transaktionsregistermeddelande i den ordning som det tas emot och skickar varje transaktion till en annan kö där kategorin är inställd på order-ID:t. En transaktion sträcker sig aldrig över flera beställningar i det här scenariot, så konsumenterna bearbetar varje kategori parallellt men FIFO inom kategorin.

Avledarprocessorn förser meddelandena med en batchbearbetning av innehållet i varje meddelande i den första kön:

Diagram som visar mönstret sekventiell konvoj med en huvudbokskö

Huvudboksprocessorn tar hand om:

  1. Gå i transaktionsboken en transaktion i taget.
  2. Ange sessions-ID för meddelandet så att det matchar order-ID:t.
  3. Skicka varje transaktionsregister till en sekundär kö med sessions-ID:t inställt på order-ID:t.

Konsumenterna lyssnar på den sekundära kön där de bearbetar alla meddelanden med matchande order-ID:er i ordning från kön. Konsumenter använder peek-lock-läge.

När du överväger skalbarhet är huvudbokskön en primär flaskhals. Olika transaktioner som publiceras i transaktionsboken kan referera till samma order-ID. Meddelanden kan dock förser efter huvudboken med antalet beställningar i en serverlös miljö.

Nästa steg

Följande information kan vara relevant när du implementerar det här mönstret: