Scénář optimalizace výkonu: distribuované obchodní transakce
Tento článek popisuje, jak vývojový tým použil metriky k nalezení kritických bodů a zlepšení výkonu distribuovaného systému. Článek vychází ze skutečného zátěžového testování, které jsme pro ukázkovou aplikaci použili. Aplikace pochází ze směrného plánu služby Azure Kubernetes (AKS) pro mikroslužby.
Tento článek je součástí série. Přečtěte si tuprvní část.
Scénář: klientská aplikace zahájí obchodní transakci, která zahrnuje několik kroků.
Tento scénář zahrnuje aplikaci pro doručování pomocí dronů, která běží na AKS. Zákazníci používají webovou aplikaci k naplánování dodávek od pomocí dronů. Každá transakce vyžaduje více kroků, které jsou prováděny samostatnými mikroslužbami v back-endu:
- Doručovací služba spravuje dodávky.
- Služba plánovače pomocí dronů plánuje DRONY zachraňují životy pro vyzvednutí.
- Služba balíčku spravuje balíčky.
Existují dvě další služby: službu ingestování, která přijímá požadavky klientů a ukládá je do fronty ke zpracování, a službu pracovního postupu, která koordinuje kroky v pracovním postupu.

Další informace o tomto scénáři najdete v tématu navrhování architektury mikroslužeb.
Test 1: směrný plán
U prvního zátěžového testu vytvořil tým cluster AKS s šesti uzly a nasadil tři repliky každé mikroslužby. Zátěžový test byl testem zátěžového testu, který začíná dvěma simulovanými uživateli a rozkládá až 40 simulovaných uživatelů.
| Nastavení | Hodnota |
|---|---|
| Uzly clusteru | 6 |
| Podů | 3 na službu |
Následující graf ukazuje výsledky zátěžového testu, jak je znázorněno v Visual Studio. Fialová čára vykresluje uživatelské zatížení a oranžový řádek vykresluje celkový počet požadavků.

První věc, kterou je potřeba využít k tomuto scénáři, je to, že požadavky klientů za sekundu nejsou užitečnou metrikou výkonu. Důvodem je, že aplikace zpracovává požadavky asynchronně, takže klient obdrží odpověď hned. Kód odpovědi je vždy HTTP 202 (přijato), což znamená, že žádost byla přijata, ale zpracování není dokončeno.
To, co opravdu chceme znát, je, zda se v back-endu zachovává frekvence požadavků. fronta Service Bus může absorbovat špičky, ale pokud back-end nedokáže zpracovat trvalé zatížení, bude zpracování zachováno ještě dál a dále.
Tady je další informativní graf. vykreslí počet příchozích a odchozích zpráv ve frontě Service Bus. Příchozí zprávy jsou zobrazovány světle modře a odchozí zprávy jsou zobrazeny tmavě modře:

Tento graf znázorňuje, že se zvyšuje rychlost příchozích zpráv, dosáhlo se špičky a pak se na konci zátěžového testu vrátí zpět na nulu. Ale počet odchozích zpráv se zachází do začátku v testu a pak se ve skutečnosti vyřazuje. To znamená, že služba pracovního postupu, která zpracovává požadavky, nezůstane zachovává. I po ukončení zátěžového testu (okolo 9:22 v grafu) se zprávy stále zpracovávají, protože služba pracovního postupu pokračuje ve vyřazení fronty.
Co zpomaluje zpracování? První věc, kterou je třeba vyhledat, jsou chyby nebo výjimky, které mohou signalizovat systematický problém. Mapa aplikace v Azure monitor zobrazuje graf volání mezi komponentami a představuje rychlý způsob, jak vymezit problémy a potom kliknutím na tlačítko získat další podrobnosti.
Je-li to nutné, mapa aplikace zobrazí, že služba pracovního postupu získává chyby ze služby doručování:

Chcete-li zobrazit další podrobnosti, můžete vybrat uzel v grafu a kliknout na koncové zobrazení transakce. V takovém případě se zobrazí, že služba doručování vrací chyby HTTP 500. Chybové zprávy označují, že se vyvolala výjimka z důvodu omezení paměti v mezipaměti Azure pro Redis.

Můžete si všimnout, že tato volání Redis se nezobrazují v mapě aplikace. to je proto, že knihovna .net pro Application Insights nemá integrovanou podporu pro sledování Redis jako závislosti. (Seznam podporovaných funkcí najdete v tématu Automatická kolekce závislostí.) Jako záložní můžete ke sledování libovolné závislosti použít rozhraní TrackDependency API. Zátěžové testování často odhaluje tyto druhy mezer v telemetrie, které je možné opravit.
Test 2: zvýšená velikost mezipaměti
Pro druhý zátěžový test zvýšil vývojový tým velikost mezipaměti v mezipaměti Azure cache pro Redis. (Viz Jak škálovat Azure cache pro Redis.) Tato změna vyřešila výjimky nedostatku paměti a teď mapa aplikace zobrazuje nulové chyby:

Stále ale dochází k výrazné prodlevě při zpracování zpráv. Ve špičce zátěžového testu je míra příchozích zpráv větší než 5 × a odchozí rychlost:

následující graf měří propustnost v souvislosti s doplňováním zpráv — , což je rychlost, s jakou služba pracovního postupu označí Service Busé zprávy jako dokončené. Každý bod v grafu představuje 5 sekund dat a zobrazuje maximální propustnost přibližně 16/s.

Tento graf byl vygenerován spuštěním dotazu v pracovním prostoru Log Analytics pomocí dotazovacího jazyka Kusto:
let start=datetime("2020-07-31T22:30:00.000Z");
let end=datetime("2020-07-31T22:45:00.000Z");
dependencies
| where cloud_RoleName == 'fabrikam-workflow'
| where timestamp > start and timestamp < end
| where type == 'Azure Service Bus'
| where target has 'https://dev-i-iuosnlbwkzkau.servicebus.windows.net'
| where client_Type == "PC"
| where name == "Complete"
| summarize succeeded=sumif(itemCount, success == true), failed=sumif(itemCount, success == false) by bin(timestamp, 5s)
| render timechart
Test 3: horizontální navýšení kapacity back-end služeb
Zdá se, že back-end je kritický bod. Jednoduchým dalším krokem je horizontální navýšení kapacity obchodních služeb (balení, doručování a pomocí dronů Scheduler) a zjištění, jestli se zvyšuje výkon. Pro další zátěžový test tým škáloval tyto služby ze tří replik na šest replik.
| Nastavení | Hodnota |
|---|---|
| Uzly clusteru | 6 |
| Služba příjmu dat | 3 repliky |
| Služba pracovního postupu | 3 repliky |
| Package, Delivery, pomocí dronů Scheduler Services | 6 replik každý |
Tento zátěžový test bohužel ukazuje pouze mírné zlepšení. Odchozí zprávy stále nepracují se příchozími zprávami:

Propustnost je větší konzistence, ale maximální dosažená hodnota je stejná jako u předchozího testu:

Kromě toho se zdá, že při Azure monitor pro kontejneryse problém nezpůsobilo vyčerpání prostředků v clusteru. Za prvé metriky na úrovni uzlu ukazují, že využití CPU zůstává pod 40% i na 95. percentilu a využití paměti je přibližně 20%.

V Kubernetes prostředí je možné, že jednotlivá Luska budou omezená na prostředky, a to i v případě, že uzly nejsou. Ale zobrazení na úrovni pod ukazuje, že všechny lusky jsou v dobrém stavu.

Z tohoto testu se zdá, že pouhým přidáním více lusků do back-endu nebude pomáhat. V dalším kroku se podíváme podrobněji na službu pracovního postupu, abyste zjistili, co se děje při zpracovávání zpráv. Application Insights ukazuje, že průměrná doba trvání operace služby pracovního postupu Process je 246 ms.

Můžeme také spustit dotaz, který získá metriky pro jednotlivé operace v rámci každé transakce:
| cílové | percentile_duration_50 | percentile_duration_95 |
|---|---|---|
https://dev-i-iuosnlbwkzkau.servicebus.windows.net/ | dev-i-iuosnlbwkzkau |
86,66950203 | 283,4255578 |
| doručení | 37 | 57 |
| package | 12 | 17 |
| dronescheduler | 21 | 41 |
první řádek v této tabulce představuje frontu Service Bus. Ostatní řádky jsou volání služby back-end. Pro referenci tady je Log Analytics dotaz pro tuto tabulku:
let start=datetime("2020-07-31T22:30:00.000Z");
let end=datetime("2020-07-31T22:45:00.000Z");
let dataset=dependencies
| where timestamp > start and timestamp < end
| where (cloud_RoleName == 'fabrikam-workflow')
| where name == 'Complete' or target in ('package', 'delivery', 'dronescheduler');
dataset
| summarize percentiles(duration, 50, 95) by target

Tyto latence vypadají rozumným způsobem. Ale tady je klíč Insight: Pokud celkový čas operace je ~ 250 ms, která představuje přísnou horní mez toho, jak se dají rychlé zprávy zpracovávat v sériovém tvaru. Klíč ke zlepšení propustnosti je proto větší paralelismu.
To by mělo být možné v tomto scénáři, a to ze dvou důvodů:
- Jedná se o síťová volání, takže většina času stráví čekání na dokončení vstupně-výstupních operací.
- Zprávy jsou nezávislé a nemusíte je zpracovávat v daném pořadí.
Test 4: zvýšení paralelismu
Pro tento test se tým zaměřuje na zvýšení paralelismu. pokud to chcete udělat, upravili jsme dvě nastavení na Service Bus klientu, který používá služba pracovního postupu:
| Nastavení | Popis | Výchozí | Nová hodnota |
|---|---|---|---|
MaxConcurrentCalls |
Maximální počet zpráv, které mají být zpracovány současně. | 1 | 20 |
PrefetchCount |
Kolik zpráv bude klient načítat před časem do místní mezipaměti. | 0 | 3000 |
další informace o těchto nastaveních najdete v tématu osvědčené postupy pro zlepšení výkonu pomocí Service Bus zasílání zpráv. Spuštění testu s tímto nastavením vyprodukuje následující graf:

Odvolat, že příchozí zprávy jsou zobrazeny modře a odchozí zprávy jsou zobrazeny tmavě modře.
Na první pohled se jedná o velmi divné graf. Za chvíli se míra odchozích zpráv přesně sleduje jenom příchozí. Ale potom v přibližně 2:03 se míra příchozích zpráv vypíná, zatímco počet odchozích zpráv se pořád zvyšuje, ale celkový počet příchozích zpráv je dál vyšší. To zřejmě není možné.
potvrzení na tento mystery najdete v zobrazení závislosti v Application Insights. Tento graf shrnuje všechna volání, která služba pracovního postupu provedla, Service Bus:

Všimněte si, že položka pro DeadLetter . tato volání označují, že se zprávy přecházejí do fronty nedoručenýchzpráv Service Bus.
Chcete-li zjistit, co se děje, je nutné pochopit sémantiku prohlížení v Service Bus. když klient používá nástroj pro prohlížení zámku, Service Bus atomicky načte a zamkne zprávu. I když je zámek uložený, zpráva se garantuje, že se nebude doručovat jiným příjemcům. Pokud zámek vyprší, bude zpráva k dispozici ostatním příjemcům. po maximálním počtu pokusů o doručení (které lze konfigurovat) Service Bus umístí zprávy do fronty nedoručenýchzpráv, kde je lze prozkoumat později.
Mějte na paměti, že služba pracovního postupu předběžné načítání velkých dávkových zpráv — 3000 zpráv. To znamená, že celková doba zpracování každé zprávy je delší, což vede k vypršení časového limitu zpráv, k návratu do fronty a nakonec ke frontě nedoručených zpráv.
Toto chování lze také zobrazit v výjimkách, kde MessageLostLockException je zaznamenáno množství výjimek:

Test 5: prodloužit dobu trvání zámku
Pro tento zátěžový test byla doba trvání zámku zprávy nastavena na 5 minut, aby se zabránilo vypršení časových limitů zámků. Graf příchozích a odchozích zpráv nyní ukazuje, že systém udržuje rychlost příchozích zpráv:

Po celkovém trvání 8 minut zátěžového testu aplikace dokončila 25 KB operací s špičkou propustnosti 72 operací/s, která představuje 400% zvýšení maximální propustnosti.

Nicméně spuštění stejného testu s delší dobou trvání ukázalo, že aplikace nemůže tolerovat tuto rychlost:

Metriky kontejneru ukazují, že maximální využití CPU bylo blízko až 100%. V tomto okamžiku se aplikace zdá být vázaná na procesor. Škálování clusteru může nyní zvýšit výkon na rozdíl od předchozího pokusu o horizontální navýšení kapacity.

Test 6: horizontální navýšení kapacity back-end služeb (znovu)
Pro finální zátěžový test v řadě tým škáluje cluster Kubernetes a lusky následujícím způsobem:
| Nastavení | Hodnota |
|---|---|
| Uzly clusteru | 12 |
| Služba příjmu dat | 3 repliky |
| Služba pracovního postupu | 6 replik |
| Package, Delivery, pomocí dronů Scheduler Services | 9 replik každý |
Výsledkem tohoto testu je vyšší dlouhodobá propustnost, bez významného prodlevy ve zpracování zpráv. Kromě toho využití CPU uzlu nechali nižší než 80%.

Souhrn
V tomto scénáři byly zjištěny následující kritické body:
- Výjimky z důvodu nedostatku paměti v mezipaměti Azure pro Redis
- Nedostatečná paralelismus při zpracování zpráv.
- Nedostatečná doba trvání zámku zprávy, což vede k uzamknutí časových limitů a zpráv umístěných do fronty nedoručených zpráv.
- Vyčerpání procesoru.
Pro diagnostiku těchto problémů vývojový tým spoléhal na následující metriky:
- míra příchozích a odchozích zpráv Service Bus.
- mapa aplikace v Application Insights.
- Chyby a výjimky.
- Vlastní dotazy Log Analytics.
- Využití CPU a paměti v Azure Monitor pro kontejnery.
Další kroky
Další informace o návrhu tohoto scénáře najdete v tématu navrhování architektury mikroslužeb.