Model prioritní fronty

Service Bus

Určuje prioritu požadavků odeslaných službám, aby se požadavky s vyšší prioritou přijímaly a zpracovávaly rychleji než požadavky s nižší prioritou. Tento model je užitečný v aplikacích, které jednotlivým klientům nabízí různé záruky úrovní služeb.

Kontext a problém

Aplikace mohou jiným službám delegovat konkrétní úlohy – například provedení zpracování na pozadí nebo integrování s jinými aplikacemi nebo službami. Fronta zpráv v cloudu se obecně používá k delegování úkolů ke zpracování na pozadí. V mnoha případech není pořadí, ve kterém jsou požadavky přijímány službou, důležité. V některých případech je ale důležité určitým žádostem zvýšit prioritu. Tyto požadavky by se měly zpracovat dříve než požadavky s nižší prioritou, které aplikace dříve odeslala.

Řešení

Fronta je obvykle struktura FIFO (first-in, first-out) a příjemci obvykle přijímají zprávy ve stejném pořadí, v jakém jsou zaúčtováni do fronty. Některé fronty zpráv ale podporují prioritní vyřizování. Aplikaci, která zprávu publikuje, může přiřadit prioritu. Zprávy ve frontě se automaticky přeuspořádají tak, aby zprávy s vyšší prioritou byly přijaty před zprávami s nižší prioritou. Tento diagram znázorňuje tento proces:

Diagram znázorňující mechanismus řazení do front, který podporuje stanovení priorit zpráv

Poznámka

Většina implementací fronty zpráv podporuje více příjemců. (Viz model Konkurující si spotřebitelé.) Počet procesů příjemce je možné vertikálně navýšit nebo snížit na základě poptávky.

U systémů, které fronty s prioritním vyřizováním zpráv nepodporují, je alternativním řešením spravovat samostatnou frontu pro každou prioritu. Aplikace je zodpovědná za odesílání zpráv do příslušné fronty. Každá fronta může mít samostatný fond příjemců. Fronty s vyšší prioritou můžou mít větší fond příjemců, kteří běží na rychlejším hardwaru než fronty s nižší prioritou. Tento diagram znázorňuje použití samostatných front zpráv pro každou prioritu:

Diagram znázorňující použití samostatných front zpráv pro každou prioritu

Variantou této strategie je implementace jednoho fondu příjemců, který nejprve zkontroluje zprávy ve frontách s vysokou prioritou a teprve potom začne načítat zprávy z front s nižší prioritou. Existují určité sémantické rozdíly mezi řešením, které používá jeden fond procesů příjemců (buď s jednou frontou, která podporuje zprávy s různými prioritami, nebo s více frontami, které každá zpracovává zprávy s jednou prioritou), a řešením, které používá více front se samostatným fondem pro každou frontu.

U přístupu s jedním fondem se zprávy s vyšší prioritou vždy přijímají a zpracovávají před zprávami s nižší prioritou. Teoreticky by zprávy s nízkou prioritou mohly být neustále nahrazovány a nemusí se nikdy zpracovávat. U přístupu s více fondy se zprávy s nižší prioritou zpracovávají vždy, ale ne tak rychle jako zprávy s vyšší prioritou (v závislosti na relativní velikosti fondů a prostředcích, které jsou pro ně k dispozici).

Použití mechanismu řazení podle priority může přinést následující výhody:

  • Umožňuje aplikacím splňovat obchodní požadavky, které vyžadují stanovení priority dostupnosti nebo výkonu, například nabízení různých úrovní služeb různým skupinám zákazníků.

  • Může pomoct minimalizovat provozní náklady. Pokud použijete přístup s jednou frontou, můžete v případě potřeby škálovat zpět počet příjemců. Zprávy s vysokou prioritou se stále zpracovávají jako první (i když možná pomaleji) a zprávy s nižší prioritou můžou být zpožděné déle. Pokud implementujete přístup s více frontami zpráv se samostatnými fondy příjemců pro každou frontu, můžete zmenšit fond příjemců pro fronty s nižší prioritou. Zpracování některých front s velmi nízkou prioritou můžete dokonce pozastavit tak, že zastavíte všechny příjemce, kteří v těchto frontách naslouchají zprávám.

  • Přístup s více frontami zpráv může díky rozdělení zpráv podle požadavků na zpracování pomoct maximalizovat výkon a škálovatelnost aplikace. Můžete například určit prioritu kritických úloh tak, aby je zpracovali příjemci, kteří se spouštějí okamžitě, a méně důležité úlohy na pozadí můžou zpracovávat příjemci, na které je naplánováno spouštění v době, kdy jsou méně zaneprázdněné.

Požadavky

Při rozhodování, jak tento model implementovat, zvažte následující body:

  • Priority definujte v kontextu řešení. Zpráva s vysokou prioritou může být například definována jako zpráva, která by měla být zpracována do 10 sekund. Identifikujte požadavky na zpracování položek s vysokou prioritou a prostředky, které je potřeba přidělit, aby splňovaly vaše kritéria.

  • Rozhodněte, jestli musí být všechny položky s vysokou prioritou zpracovány před položkami s nižší prioritou. Pokud zprávy zpracovává jeden fond příjemců, musíte poskytnout mechanismus, který může zrušit a pozastavit úlohu, která zpracovává zprávu s nízkou prioritou, pokud do fronty vstoupí zpráva s vyšší prioritou.

  • Pokud u přístupu s více frontami používáte jeden fond procesů příjemců, které naslouchají všem frontám, nikoli vyhrazený fond příjemců pro každou frontu, musí příjemce použít algoritmus, který zajistí, že zprávy z front s vyšší prioritou vždy obsluhuje před zprávami z front s nižší prioritou.

  • Sledujte rychlost zpracování front s vysokou a nízkou prioritou, abyste zajistili, že se zprávy v těchto frontách zpracovávají očekávaným tempem.

  • Pokud potřebujete zaručit zpracování zpráv s nízkou prioritou, implementujte přístup s více frontami zpráv s více fondy příjemců. Případně můžete ve frontě, která podporuje stanovení priority zpráv, dynamicky zvyšovat prioritu zprávy ve frontě, jak stárne. Tento přístup ale závisí na frontě zpráv, která tuto funkci poskytuje.

  • Strategie používání samostatných front na základě priority zpráv se doporučuje pro systémy, které mají několik dobře definovaných priorit.

  • Systém může logicky určit priority zpráv. Například místo explicitních zpráv s vysokou a nízkou prioritou můžete zprávy označit jako "platící zákazník" nebo "neplatící zákazník". Váš systém by pak mohl přidělit více prostředků na zpracování zpráv od platících zákazníků.

  • S kontrolou fronty pro zprávu můžou být spojené finanční náklady a náklady na zpracování. Některé komerční systémy zasílání zpráv například účtují malý poplatek za každé publikování nebo načtení zprávy a pokaždé, když se na zprávy dotazuje fronta. Tyto náklady se zvýší, když zkontrolujete více front.

  • Velikost fondu příjemců můžete dynamicky upravit na základě délky fronty, kterou fond obsluhuje. Další informace najdete v pokynech k automatickému škálování.

Kdy se má tento model použít

Tento model je vhodný pro následující scénáře:

  • Systém musí zpracovat více úloh, které mají různé priority.

  • Různí uživatelé nebo tenanti by se měli obsluhovat s různými prioritami.

Příklad

Azure neposkytuje mechanismus řazení do fronty, který nativně podporuje automatické stanovení priority zpráv prostřednictvím řazení. Poskytuje ale Azure Service Bus témata, odběry služby Service Bus, které podporují mechanismus řazení do front, který poskytuje filtrování zpráv, a řadu flexibilních funkcí, díky kterým je Azure ideální pro většinu implementací prioritní fronty.

Řešení Azure může implementovat téma služby Service Bus, do kterého může aplikace publikovat zprávy, stejně jako by je odsílala do fronty. Zprávy mohou obsahovat metadata ve formě vlastních vlastností definovaných aplikací. K tématu můžete přidružit odběry služby Service Bus a odběry můžou filtrovat zprávy na základě jejich vlastností. Když aplikace odešle zprávu do tématu, zpráva se směruje do příslušného odběru, kde si ji příjemce může přečíst. Procesy příjemce můžou načítat zprávy z odběru pomocí stejné sémantiky, kterou by používaly s frontou zpráv. (Odběr je logická fronta.) Tento diagram ukazuje, jak implementovat prioritní frontu pomocí témat a odběrů služby Service Bus:

Diagram znázorňující, jak implementovat prioritní frontu pomocí témat a odběrů služby Service Bus

V předchozím diagramu aplikace vytvoří několik zpráv a v každé zprávě přiřadí vlastní vlastnost s názvem Priority . Priority má hodnotu High nebo Low. Aplikace tyto zprávy odešle do tématu. Téma má dva přidružené odběry, které filtrují zprávy na Priority základě vlastnosti . Jeden odběr přijímá zprávy s vlastností nastavenou Priority na High. Druhý přijímá zprávy s vlastností nastavenou Priority na Low. Fond příjemců čte zprávy z každého odběru. Předplatné s vysokou prioritou má větší fond a tito příjemci můžou být spuštěni na výkonnějších počítačích, které mají více dostupných prostředků než počítače pro fond s nízkou prioritou.

V tomto příkladu není na označení zpráv s vysokou a nízkou prioritou nic zvláštního. Jsou to jednoduše popisky, které jsou v každé zprávě zadané jako vlastnosti. Slouží ke směrování zpráv do konkrétního odběru. Pokud jsou potřeba další priority, je poměrně snadné vytvořit více předplatných a fondů procesů příjemců, aby se tyto priority zvládly.

Řešení PriorityQueue na GitHubu je založené na tomto přístupu. Toto řešení obsahuje projekty Azure Functions s názvem PriorityQueueConsumerHigh a PriorityQueueConsumerLow. Tyto projekty Azure Functions se integrují se službou Service Bus prostřednictvím triggerů a vazeb. Připojují se k různým předplatným definovaným v ServiceBusTrigger a reagují na příchozí zprávy.

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}");
    }
}

Jako správce můžete nakonfigurovat, na kolik instancí můžou funkce na Azure App Service škálovat. Můžete to udělat tak, že v Azure Portal nakonfigurujete možnost Vynutit limit horizontálního navýšení kapacity a nastavíte maximální limit horizontálního navýšení kapacity pro každou funkci. Obvykle potřebujete mít více instancí PriorityQueueConsumerHigh funkce než PriorityQueueConsumerLow funkce . Tato konfigurace zajišťuje, že se zprávy s vysokou prioritou čtou z fronty rychleji než zprávy s nízkou prioritou.

Jiný projekt , PriorityQueueSenderobsahuje časově aktivovanou funkci Azure, která je nakonfigurovaná tak, aby se spouštěla každých 30 sekund. Tato funkce se integruje se službou Service Bus prostřednictvím výstupní vazby a odesílá dávky zpráv s nízkou a vysokou prioritou do objektu IAsyncCollector . Když funkce publikuje zprávy do tématu, které je přidružené k odběrům používaným funkcemi PriorityQueueConsumerHigh a PriorityQueueConsumerLow , určuje prioritu pomocí Priority vlastní vlastnosti, jak je znázorněno tady:

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);
        }
    }
}

Další kroky

Při implementaci tohoto modelu pro vás můžou být užitečné následující zdroje informací:

Při implementaci tohoto vzoru pro vás můžou být užitečné následující vzory:

  • Model konkurenčních spotřebitelů: Pokud chcete zvýšit propustnost front, můžete implementovat více příjemců, kteří naslouchají ve stejné frontě a zpracovávají úlohy paralelně. Tito příjemci soutěží o zprávy, ale pouze jeden by měl být schopen zpracovat každou zprávu. Tento článek obsahuje další informace o výhodách a nevýhodách implementace tohoto přístupu.

  • Model omezení využití sítě. Omezení využití sítě můžete implementovat použitím front. Prioritní zasílání zpráv můžete použít k zajištění toho, aby požadavky z důležitých aplikací nebo aplikací, které provozují zákazníci s vysokou hodnotou, dostaly přednost před požadavky z méně důležitých aplikací.