Elsőbbségi üzenetsor mintája

Azure Service Bus

Priorizálhatja a szolgáltatásoknak küldött kéréseket úgy, hogy a magasabb prioritású kéréseket a rendszer gyorsabban fogadja és dolgozza fel, mint az alacsonyabb prioritásúakat. Ez a minta olyan alkalmazások esetében hasznos, amelyek különböző szolgáltatási szintre vonatkozó garanciákat kínálnak az egyes ügyfelek számára.

Kontextus és probléma

Az alkalmazások bizonyos feladatokat delegálhatnak más szolgáltatások számára, például a háttérfeldolgozás végrehajtását vagy a más alkalmazásokkal/szolgáltatásokkal való integrációt. A felhőben az üzenetsorokat jellemzően a feladatok háttérbeli feldolgozásra való delegálására használjuk. Sok esetben nem fontos, hogy a kérések milyen sorrendben érkeznek egy szolgáltatáshoz. Néha azonban meg kell határozni bizonyos kérelmek prioritását. Ezeket a kéréseket korábban kell feldolgozni, mint az alkalmazás által korábban elküldött alacsonyabb prioritású kérelmeket.

Megoldás

Az üzenetsorok általában első be- és kimenő (FIFO) struktúrát használnak, és a felhasználók általában ugyanabban a sorrendben fogadják az üzeneteket, mint amelyeket az üzenetsorba tesznek közzé. Bizonyos üzenetsorok azonban támogatják a prioritásalapú üzenetkezelést is. Az üzenetet közzétenő alkalmazás hozzárendelhet egy prioritást. Az üzenetsor üzenetei automatikusan átrendeződnek, hogy a magasabb prioritású üzenetek az alacsonyabb prioritású üzenetek előtt érkezhessenek meg. Ez az ábra a folyamatot szemlélteti:

Az üzenet rangsorolását támogató üzenetsor-kezelési mechanizmust bemutató ábra.

Feljegyzés

A legtöbb üzenetsor-implementáció több felhasználót támogat. (Lásd: Versengő fogyasztók mintája.) A fogyasztói folyamatok száma igény szerint fel- és leskálázható.

Olyan rendszerekben, amelyek nem támogatják a prioritásalapú üzenetsorokat, alternatív megoldásként külön sorokat tarthatunk fenn a prioritások számára. Az alkalmazás feladata az üzenetek megfelelő üzenetsorban történő közzététele. Minden egyes üzenetsorhoz külön fogyasztók tartozhatnak. A magasabb prioritású üzenetsorok nagyobb felhasználói készlettel rendelkezhetnek, amelyek gyorsabb hardveren futnak, mint az alacsonyabb prioritású üzenetsorok. Ez az ábra az egyes prioritásokhoz tartozó külön üzenetsorok használatát mutatja be:

Diagram, amely az egyes prioritásokhoz tartozó üzenetsorok használatát mutatja be.

A stratégia egyik változata, hogy egyetlen olyan felhasználói készletet implementál, amely először a magas prioritású üzenetsorokon ellenőrzi az üzeneteket, és csak ezt követően kezdi lekérni az üzeneteket az alacsonyabb prioritású üzenetsorokból. Van néhány szemantikai különbség egy olyan megoldás között, amely egyetlen fogyasztói folyamatkészletet használ (vagy egyetlen üzenetsort használ, amely támogatja a különböző prioritású üzeneteket, vagy több üzenetsorsal, amelyek mindegyike egyetlen prioritású üzeneteket kezel), és egy olyan megoldás, amely több üzenetsort használ, és mindegyik üzenetsorhoz külön készletet használ.

Az egykészletes megközelítésben a magasabb prioritású üzenetek mindig az alacsonyabb prioritású üzenetek előtt érkeznek és dolgozhatók fel. Elméletileg az alacsony prioritású üzeneteket folyamatosan lehet felülírni, és soha nem lehet feldolgozni. A többkészletes megközelítésben az alacsonyabb prioritású üzenetek mindig feldolgozásra kerülnek, de nem olyan gyorsan, mint a magasabb prioritású üzenetek (a készletek relatív méretétől és a számukra elérhető erőforrásoktól függően).

A prioritási sorba állítási mechanizmus használata a következő előnyöket nyújthatja:

  • Lehetővé teszi, hogy az alkalmazások megfeleljenek az olyan üzleti követelményeknek, amelyek megkövetelik a rendelkezésre állás vagy a teljesítmény rangsorolását, például különböző szolgáltatási szinteket kínálnak különböző ügyfélcsoportok számára.

  • Hozzájárulhat az üzemeltetési költségek minimálisra csökkentéséhez. Ha az egysoros megközelítést használja, szükség esetén visszaskálázhatja a fogyasztók számát. A magas prioritású üzenetek feldolgozása még mindig elsőként történik (bár valószínűleg lassabban), és az alacsonyabb prioritású üzenetek hosszabb ideig késhetnek. Ha több üzenetsor-megközelítést valósít meg az egyes üzenetsorokhoz tartozó különböző felhasználói készletekkel, csökkentheti az alacsonyabb prioritású üzenetsorok felhasználói készletét. Néhány nagyon alacsony prioritású üzenetsor feldolgozását is felfüggesztheti, ha leállítja az üzeneteket figyelő összes felhasználót az üzenetsorokon.

  • A többüzenetsoros megközelítés révén maximalizálható az alkalmazások teljesítménye és skálázhatósága az üzenetek feldolgozási követelményeken alapuló particionálásával. Rangsorolhatja például a kritikus feladatokat, hogy azokat az azonnal futó fogadók kezeljék, a kevésbé fontos háttérfeladatokat pedig olyan fogadók kezelhetik, amelyek az ütemezés szerint kevésbé elfoglalt időpontokban futnak.

Megfontolások

Vegye figyelembe a következő szempontokat, amikor úgy dönt, hogy hogyan valósítja meg ezt a mintát:

  • Határozza meg a prioritásokat a megoldás tekintetében. Egy magas prioritású üzenet például 10 másodpercen belül feldolgozandó üzenetként definiálható. Azonosítsa a magas prioritású elemek kezelésének követelményeit és a feltételeknek való megfeleléshez lefoglalandó erőforrásokat.

  • Döntse el, hogy az összes magas prioritású elemet az alacsonyabb prioritású elemek előtt kell-e feldolgozni. Ha az üzeneteket egyetlen felhasználói készlet dolgozza fel, olyan mechanizmust kell biztosítania, amely elő tudja írni és felfüggeszteni azt a feladatot, amely alacsony prioritású üzenetet kezel, ha egy magasabb prioritású üzenet lép be az üzenetsorba.

  • A többsoros megközelítésben, ha egyetlen olyan fogyasztói folyamatkészletet használ, amely minden üzenetsort figyel, nem pedig egy dedikált fogyasztói készletet minden üzenetsorhoz, a fogyasztónak olyan algoritmust kell alkalmaznia, amely biztosítja, hogy mindig a magasabb prioritású üzenetsorokból érkező üzeneteket használja, mielőtt az alacsonyabb prioritású üzenetsorokból érkező üzeneteket figyeli.

  • A magas és alacsony prioritású üzenetsorok feldolgozási sebességének figyelése annak biztosítása érdekében, hogy az üzenetsorokban lévő üzenetek feldolgozása a várt sebességgel történjen.

  • Ha garantálnia kell az alacsony prioritású üzenetek feldolgozását, implementálja a több üzenetsoros megközelítést több felhasználói készlettel. Azt is megteheti, hogy az üzenetpriorizálást támogató üzenetsorokban dinamikusan növelheti az üzenetsorba helyezett üzenetek prioritását az életkorának megfelelően. Ezen megközelítés megvalósíthatósága azonban a funkciót biztosító üzenetsortól függ.

  • Az üzenet prioritásán alapuló különálló üzenetsorok használatának stratégiája olyan rendszerek esetében ajánlott, amelyek néhány jól meghatározott prioritással rendelkeznek.

  • A rendszer logikailag meg tudja határozni az üzenet prioritásait. Például ahelyett, hogy kifejezetten magas és alacsony prioritású üzeneteket tartalmazna, "fizető ügyfélként" vagy "nem fizető ügyfélként" jelölheti meg az üzeneteket. A rendszer ezután további erőforrásokat oszthat ki a fizető ügyfelektől érkező üzenetek feldolgozásához.

  • Előfordulhat, hogy egy üzenetsor ellenőrzésének pénzügyi és feldolgozási költsége van. Egyes kereskedelmi üzenetkezelési rendszerek például kis díjat számítanak fel minden egyes üzenet közzétételekor vagy lekérésekor, és minden alkalommal, amikor üzenetsort kérdeznek le az üzenetekért. Ez a költség több üzenetsor ellenőrzésekor nő.

  • A készlet által karbantartott üzenetsor hossza alapján dinamikusan módosíthatja a felhasználói készlet méretét. További információ: Automatikus skálázási útmutató.

Mikor érdemes ezt a mintát használni?

Ez a minta az alábbi forgatókönyvekben hasznos:

  • A rendszernek több olyan feladatot kell kezelnie, amelyek eltérő prioritásokkal rendelkeznek.

  • A különböző felhasználókat vagy bérlőket különböző prioritásokkal kell kiszolgálni.

Számítási feladatok tervezése

Az építészeknek értékelniük kell, hogy a prioritási üzenetsor mintája hogyan használható a számítási feladat tervezése során az Azure Well-Architected Framework pilléreiben foglalt célok és alapelvek kezelésére. Példa:

Pillér Hogyan támogatja ez a minta a pillércélokat?
A megbízhatósági tervezési döntések segítenek a számítási feladatnak ellenállóvá válni a hibás működéssel szemben, és biztosítani, hogy a hiba bekövetkezése után teljesen működőképes állapotba kerüljön. Az üzleti prioritás alapján elválasztó elemek lehetővé teszik, hogy a megbízhatósági erőfeszítéseket a legkritikusabb munkára összpontosítsa.

- RE:02 Kritikus folyamatok
- RE:07 Háttérfeladatok
A teljesítményhatékonyság a skálázás, az adatok és a kód optimalizálásával segíti a számítási feladatok hatékony kielégítését . Az üzleti prioritás alapján elválasztó elemek lehetővé teszik, hogy a teljesítményre irányuló erőfeszítéseket a leginkább időérzékeny munkára összpontosítsa.

- PE:09 Kritikus folyamatok

Mint minden tervezési döntésnél, fontolja meg az ezzel a mintával bevezethető többi pillér céljaival szembeni kompromisszumokat.

Példa

Az Azure nem biztosít olyan üzenetsor-kezelési mechanizmust, amely natív módon támogatja az üzenetek automatikus rangsorolását rendezéssel. Azonban biztosít Azure Service Bus-témaköröket, olyan Service Bus-előfizetéseket, amelyek támogatják az üzenetszűrést biztosító üzenetsor-kezelési mechanizmust, valamint számos rugalmas képességet, amelyek ideálissá teszik az Azure-t a legtöbb prioritási üzenetsor-implementációhoz.

Az Azure-megoldások implementálhatnak egy Service Bus-témakört, amelybe az alkalmazás üzeneteket tehet közzé, ahogyan az üzenetsorba tenné őket. Az üzenetek alkalmazások által meghatározott egyéni tulajdonságok formájában metaadatokat tartalmazhatnak. Service Bus-előfizetéseket társíthat a témakörhöz, és az előfizetések a tulajdonságaik alapján szűrhetik az üzeneteket. Amikor egy alkalmazás üzenetet küld egy témakörnek, az üzenet a megfelelő előfizetéshez lesz irányítva, ahol a fogyasztó elolvashatja. A fogyasztói folyamatok ugyanazt a szemantikát használják az előfizetésből, mint az üzenetsorhoz. (Az előfizetés egy logikai üzenetsor.) Ez az ábra bemutatja, hogyan valósíthat meg prioritási üzenetsort Service Bus-témakörök és -előfizetések használatával:

Diagram, amely bemutatja, hogyan valósíthat meg prioritási üzenetsort Service Bus-témakörök és -előfizetések használatával.

Az előző ábrán az alkalmazás több üzenetet hoz létre, és hozzárendel egy egyéni tulajdonságot, amelyet minden üzenetben meghív Priority . Priority értéke High vagy Lowértéke . Az alkalmazás ezeket az üzeneteket közzéteszi egy témakörbe. A témakör két társított előfizetéssel rendelkezik, amelyek a tulajdonság alapján szűrik az Priority üzeneteket. Az egyik előfizetés a következő tulajdonsággal PriorityHighfogad üzeneteket: . A másik a következő tulajdonságú PriorityLowüzeneteket fogadja el: . Az egyes előfizetésekből fogyasztókészletek olvassák az üzeneteket. A magas prioritású előfizetés nagyobb készletet tartalmaz, és ezek a felhasználók nagyobb teljesítményű számítógépeken futnak, amelyek több erőforrással rendelkeznek, mint az alacsony prioritású készlethez tartozó számítógépek.

Ebben a példában semmi különös nincs a magas és alacsony prioritású üzenetek megjelölésével kapcsolatban. Ezek egyszerűen címkék, amelyek tulajdonságokként vannak megadva az egyes üzenetekben. Ezek az üzenetek egy adott előfizetéshez való irányítására szolgálnak. Ha további prioritásokra van szükség, viszonylag könnyű több előfizetést és fogyasztói folyamatkészletet létrehozni a prioritások kezeléséhez.

A PriorityQueue megoldás a GitHubon ezen a megközelítésen alapul. Ez a megoldás a nevesített PriorityQueueConsumerHighPriorityQueueConsumerLowAzure-függvényprojekteket tartalmazza. Ezek az Azure-függvényprojektek triggereken és kötéseken keresztül integrálhatók a Service Bus szolgáltatással. Különböző előfizetésekhez csatlakoznak, amelyek definiálva ServiceBusTrigger vannak, és reagálnak a bejövő üzenetekre.

public static class PriorityQueueConsumerHighFn
{
    [FunctionName("HighPriorityQueueConsumerFunction")]
    public static void Run(
      [ServiceBusTrigger("messages", "highPriority", Connection = "ServiceBusConnection")]string highPriorityMessage,
      ILogger log)
    {
        log.LogInformation($"C# ServiceBus topic trigger function processed message: {highPriorityMessage}");
    }
}

Rendszergazdaként konfigurálhatja, hogy hány példányra méretezhetők fel a Azure-alkalmazás szolgáltatás funkciói. Ezt úgy teheti meg, hogy konfigurálja a Vertikális felskálázási korlát kényszerítése beállítást az Azure Portalon, és beállítja az egyes függvények maximális vertikális felskálázási korlátját. A függvénynek általában több példánya kell, hogy legyen, PriorityQueueConsumerHigh mint a PriorityQueueConsumerLow függvénynek. Ez a konfiguráció biztosítja, hogy a magas prioritású üzenetek gyorsabban legyenek beolvasva az üzenetsorból, mint az alacsony prioritású üzenetek.

Egy másik projekt, PriorityQueueSenderegy idővezérelt Azure-függvényt tartalmaz, amely 30 másodpercenkénti futtatásra van konfigurálva. Ez a függvény egy kimeneti kötésen keresztül integrálható a Service Bus szolgáltatással, és alacsony és magas prioritású üzenetek kötegeit küldi el egy IAsyncCollector objektumnak. Amikor a függvény üzeneteket küld a témakörbe, amely az és PriorityQueueConsumerLow a függvények által PriorityQueueConsumerHigh használt előfizetésekhez van társítva, az egyéni tulajdonság használatával határozza meg a Priority prioritást, az itt látható módon:

public static class PriorityQueueSenderFn
{
    [FunctionName("PriorityQueueSenderFunction")]
    public static async Task Run(
        [TimerTrigger("0,30 * * * * *")] TimerInfo myTimer,
        [ServiceBus("messages", Connection = "ServiceBusConnection")] IAsyncCollector<ServiceBusMessage> collector)
    {
        for (int i = 0; i < 10; i++)
        {
            var messageId = Guid.NewGuid().ToString();
            var lpMessage = new ServiceBusMessage() { MessageId = messageId };
            lpMessage.ApplicationProperties["Priority"] = Priority.Low;
            lpMessage.Body = BinaryData.FromString($"Low priority message with Id: {messageId}");
            await collector.AddAsync(lpMessage);

            messageId = Guid.NewGuid().ToString();
            var hpMessage = new ServiceBusMessage() { MessageId = messageId };
            hpMessage.ApplicationProperties["Priority"] = Priority.High;
            hpMessage.Body = BinaryData.FromString($"High priority message with Id: {messageId}");
            await collector.AddAsync(hpMessage);
        }
    }
}

Következő lépések

A következő erőforrások hasznosak lehetnek a minta megvalósításakor:

  • Ez a minta a GitHubon mutatja be ezt a mintát.

  • Aszinkron üzenetkezelési alapozó. Lehetséges, hogy a kérelmet feldolgozó fogyasztói szolgáltatásnak választ kell küldenie a kérelmet közzétevő alkalmazáspéldány számára. Ez a cikk a kérések/válaszok üzenetkezelésének megvalósításához használható stratégiákról nyújt tájékoztatást.

  • Automatikus skálázási útmutató. Időnként skálázhatja az üzenetsort kezelő fogyasztói folyamatok készletének méretét az üzenetsor hossza alapján. Ez a stratégia segíthet a teljesítmény javításában, különösen a magas prioritású üzeneteket kezelő készletek esetében.

A következő minták hasznosak lehetnek a minta megvalósításakor:

  • Versengő felhasználókat ismertető minta. Az üzenetsorok átviteli sebességének növeléséhez több olyan felhasználót is implementálhat, amelyek ugyanazon az üzenetsoron figyelnek, és párhuzamosan dolgozzák fel a feladatokat. Ezek a fogyasztók versengenek az üzenetekért, de csak egynek kell tudnia feldolgozni az egyes üzeneteket. Ez a cikk további információkat nyújt a megközelítés végrehajtásának előnyeiről és hátrányairól.

  • Szabályozási minta. A szabályozás üzenetsorok használatával valósítható meg. A prioritásos üzenetkezeléssel biztosíthatja, hogy a kritikus alkalmazásoktól vagy a nagy értékű ügyfelek által futtatott alkalmazásoktól érkező kérelmek elsőbbséget élveznek a kevésbé fontos alkalmazások kéréseinél.