Aspekty návrhu aplikací pro klíčové úlohy
Základní referenční architektura kritická pro základní účely používá jednoduchou aplikaci online katalogu k ilustraci vysoce spolehlivé úlohy. Uživatelé můžou procházet katalog položek, kontrolovat podrobnosti o položkách a publikovat hodnocení a komentáře k položkám. Tento článek se zaměřuje na aspekty spolehlivosti a odolnosti klíčové aplikace, jako je asynchronní zpracování požadavků a jak dosáhnout vysoké propustnosti v rámci řešení.
Důležité
Referenční implementace na produkční úrovni, která předvádí důležitý vývoj aplikací na podpora Azure pokyny v tomto článku. Tuto implementaci můžete použít jako základ pro další vývoj řešení v prvním kroku směrem k produkčnímu prostředí.
Složení aplikace
U vysoce důležitých aplikací musíte optimalizovat architekturu pro komplexní škálovatelnost a odolnost. Komponenty můžete oddělit do funkčních jednotek, které mohou fungovat nezávisle. Toto oddělení použijte na všech úrovních zásobníku aplikací, aby každá část systému byla možné škálovat nezávisle a uspokojovat změny v poptávce. Tato implementace ukazuje tento přístup.
Aplikace používá bezstavové koncové body rozhraní API, které oddělují dlouhotrvající požadavky na zápis asynchronně prostřednictvím zprostředkovatele zasílání zpráv. Složení úlohy umožňuje kdykoli odstranit a znovu vytvořit celé clustery Azure Kubernetes Service (AKS) a další závislosti v razítku. Mezi hlavní komponenty aplikace patří:
Uživatelské rozhraní (UI):: Jednostráková webová aplikace, ke které mají uživatelé přístup. Uživatelské rozhraní je hostované na hostování statického webu účtu Azure Storage.
API (
CatalogService
): Rozhraní REST API, které volá aplikace uživatelského rozhraní, ale je stále k dispozici pro další potenciální klientské aplikace.Pracovní proces (
BackgroundProcessor
): Pracovní proces na pozadí, který naslouchá novým událostem ve sběrnici zpráv a zpracovává požadavky na zápis do databáze. Tato komponenta nezpřístupňuje žádná rozhraní API.Rozhraní API služby Health Service (
HealthService
): Rozhraní API, které hlásí stav aplikace kontrolou, jestli fungují důležité komponenty, jako je databáze nebo sběrnice zasílání zpráv.
Úloha se skládá z aplikací pro rozhraní API, pracovní proces a kontrolu stavu. Vyhrazený obor názvů AKS, který se nazývá workload
hostuje úlohy jako kontejnery. Mezi pody nedojde k přímé komunikaci. Pody jsou bezstavové a můžou se škálovat nezávisle.
Mezi další podpůrné komponenty, které běží v clusteru, patří:
Kontroler příchozího přenosu dat NGINX: Směruje příchozí požadavky na úlohy a vyrovnávání zatížení mezi pody. Kontroler příchozího přenosu dat NGINX je přístupný přes Azure Load Balancer s veřejnou IP adresou, ale dá se k němu přistupovat jenom přes Azure Front Door.
Cert manager: Jetstack autoprovisions
cert-manager
Transport Layer Security (TLS) certifikáty pomocí Let's Encrypt pro pravidla příchozího přenosu dat.Ovladač CSI úložiště tajných kódů: Zprostředkovatel služby Azure Key Vault pro ovladač CSI úložiště tajných kódů bezpečně čte tajné kódy, jako jsou připojovací řetězec ze služby Key Vault.
Agent monitorování: Výchozí konfigurace OMSAgentForLinux se upraví tak, aby se snížilo množství dat monitorování odesílaných do pracovního prostoru protokolů služby Azure Monitor.
Připojení k databázi
Vzhledem k dočasné povaze kolků nasazení se vyhněte zachování stavu v kolku co nejvíce. V externím úložišti dat byste měli zachovat stav. Pro podporu cíle na úrovni služby spolehlivosti (SLO) vytvořte odolné úložiště dat. Doporučujeme používat řešení spravovaná nebo platforma jako služba (PaaS) v kombinaci s nativními knihovnami SDK, které automaticky zpracovávají časové limity, odpojení a další stavy selhání.
V referenční implementaci slouží Azure Cosmos DB jako hlavní úložiště dat pro aplikaci. Azure Cosmos DB poskytuje zápisy do více oblastí. Každé razítko může zapisovat do repliky služby Azure Cosmos DB ve stejné oblasti a Azure Cosmos DB interně zpracovává replikaci a synchronizaci dat mezi oblastmi. Azure Cosmos DB for NoSQL podporuje všechny funkce databázového stroje.
Další informace najdete v tématu Datová platforma pro klíčové úlohy.
Poznámka:
Pro nové aplikace použijte Azure Cosmos DB for NoSQL. U starších aplikací, které používají jiný protokol NoSQL, vyhodnoťte cestu migrace ke službě Azure Cosmos DB.
Pro klíčové aplikace, které upřednostňují dostupnost oproti výkonu, doporučujeme čtení s jednou oblastí a čtení ve více oblastech se silnou úrovní konzistence .
Tato architektura používá úložiště k dočasnému uložení stavu v razítku pro vytváření kontrolních bodů služby Azure Event Hubs.
Všechny komponenty úloh používají sadu .NET Core SDK služby Azure Cosmos DB ke komunikaci s databází. Sada SDK obsahuje robustní logiku pro údržbu připojení k databázi a zpracování selhání. Mezi nastavení konfigurace klíče patří:
Režim přímého připojení: Toto nastavení je výchozí pro sadu .NET SDK v3, protože nabízí lepší výkon. Režim přímého připojení má v porovnání s režimem brány méně segmentů směrování sítě, které používá protokol HTTP.
Odpověď na zpětný obsah při zápisu: Tento přístup je zakázaný, aby klient služby Azure Cosmos DB nemohl vrátit dokument z operací vytvoření, upsertu a oprav a nahrazení, což snižuje síťový provoz. Další zpracování na klientovi nevyžaduje toto nastavení.
Vlastní serializace: Tento proces nastaví zásadu pojmenování vlastností JSON tak, aby
JsonNamingPolicy.CamelCase
přeložil vlastnosti .NET na standardní vlastnosti JSON. Může také přeložit vlastnosti JSON na vlastnosti .NET. Výchozí podmínka ignorování ignoruje vlastnosti s hodnotami null, napříkladJsonIgnoreCondition.WhenWritingNull
, během serializace.ApplicationRegion: Tato vlastnost je nastavena na oblast razítka, která sadě SDK umožňuje najít nejbližší koncový bod připojení. Koncový bod by měl být nejlépe ve stejné oblasti.
Následující blok kódu se zobrazí v referenční implementaci:
//
// /src/app/AlwaysOn.Shared/Services/CosmosDbService.cs
//
CosmosClientBuilder clientBuilder = new CosmosClientBuilder(sysConfig.CosmosEndpointUri, sysConfig.CosmosApiKey)
.WithConnectionModeDirect()
.WithContentResponseOnWrite(false)
.WithRequestTimeout(TimeSpan.FromSeconds(sysConfig.ComsosRequestTimeoutSeconds))
.WithThrottlingRetryOptions(TimeSpan.FromSeconds(sysConfig.ComsosRetryWaitSeconds), sysConfig.ComsosMaxRetryCount)
.WithCustomSerializer(new CosmosNetSerializer(Globals.JsonSerializerOptions));
if (sysConfig.AzureRegion != "unknown")
{
clientBuilder = clientBuilder.WithApplicationRegion(sysConfig.AzureRegion);
}
_dbClient = clientBuilder.Build();
Asynchronní zasílání zpráv
Když implementujete volné párování, služby nemají závislosti na jiných službách. Volný aspekt umožňuje, aby služba fungovala nezávisle. Aspekt párování umožňuje komunikaci mezi službami prostřednictvím dobře definovaných rozhraní. Pro kritickou aplikaci volné párování zabraňuje selháním podřízených procesů kaskádově až po front-endy nebo jiné razítka nasazení, což zajišťuje vysokou dostupnost.
Mezi klíčové charakteristiky asynchronního zasílání zpráv patří:
Služby nemusí používat stejnou výpočetní platformu, programovací jazyk ani operační systém.
Služby se škáluje nezávisle.
Podřízená selhání nemají vliv na klientské transakce.
Transakční integrita se obtížně udržuje, protože vytváření a trvalost dat probíhá v samostatných službách. Transakční integrita je výzvou napříč službami zasílání zpráv a trvalosti. Další informace naleznete v tématu Idempotentní zpracování zpráv.
Kompletní trasování vyžaduje komplexní orchestraci.
Doporučujeme používat dobře známé vzory návrhu, jako je model vyrovnávání zatížení založený na frontě a model Konkurenční spotřebitelé. Tyto vzory distribuují zatížení od producenta do příjemců a umožňují asynchronní zpracování podle příjemců. Pracovní proces například umožňuje rozhraní API přijmout požadavek a rychle se vrátit volajícímu a pracovní proces zpracuje operaci zápisu databáze samostatně.
Event Hubs zprostředkuje zprávy mezi rozhraním API a pracovním procesem.
Důležité
Nepoužívejte zprostředkovatele zpráv jako trvalé úložiště dat po dlouhou dobu. Služba Event Hubs podporuje funkci zachycení. Funkce zachycení umožňuje centru událostí automaticky zapisovat kopii zpráv do propojeného účtu úložiště. Tento proces řídí využití a slouží jako mechanismus pro zálohování zpráv.
Podrobnosti implementace operací zápisu
Operace zápisu, jako je hodnocení příspěvku a komentář, se zpracovávají asynchronně. Rozhraní API nejprve odešle zprávu se všemi relevantními informacemi, jako je typ akce a data komentářů, do fronty zpráv a okamžitě se vrátí HTTP 202 (Accepted)
s Location
hlavičkou objektu, který se vytvoří.
BackgroundProcessor
instance zpracovávají zprávy ve frontě a zpracovávají skutečnou komunikaci databáze pro operace zápisu. BackgroundProcessor
škáluje a škáluje se dynamicky na základě svazku zpráv fronty. Limit horizontálního navýšení kapacity instancí procesoru je definován maximálním počtem oddílů služby Event Hubs, což je 32 pro úrovně Basic a úrovně Standard, 100 pro úroveň Premium a 1 024 pro vyhrazenou úroveň.
Knihovna procesoru Azure Event Hubs ve BackgroundProcessor
službě Azure Blob Storage používá ke správě vlastnictví oddílů, vyrovnávání zatížení mezi různými instancemi pracovních procesů a sledování průběhu pomocí kontrolních bodů. Kontrolní body se po každé události nezapisují do úložiště objektů blob, protože pro každou zprávu přidává nákladné zpoždění. Místo toho jsou kontrolní body napsané ve smyčce časovače a můžete nakonfigurovat dobu trvání. Výchozí nastavení je 10 sekund.
Následující blok kódu se zobrazí v referenční implementaci:
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(_sysConfig.BackendCheckpointLoopSeconds), stoppingToken);
if (!stoppingToken.IsCancellationRequested && !checkpointEvents.IsEmpty)
{
string lastPartition = null;
try
{
foreach (var partition in checkpointEvents.Keys)
{
lastPartition = partition;
if (checkpointEvents.TryRemove(partition, out ProcessEventArgs lastProcessEventArgs))
{
if (lastProcessEventArgs.HasEvent)
{
_logger.LogDebug("Scheduled checkpointing for partition {partition}. Offset={offset}", partition, lastProcessEventArgs.Data.Offset);
await lastProcessEventArgs.UpdateCheckpointAsync();
}
}
}
}
catch (Exception e)
{
_logger.LogError(e, "Exception during checkpointing loop for partition={lastPartition}", lastPartition);
}
}
}
Pokud aplikace procesoru narazí na chybu nebo je zastavena, než může zprávu zpracovat:
Další instance převezme zprávu pro opětovné zpracování, protože nebyla správně označena ve službě Storage.
Ke konfliktu dojde v případě, že předchozí pracovní proces zachoval dokument v databázi před selháním pracovního procesu. K této chybě dochází, protože se používá stejné ID a klíč oddílu. Procesor může zprávu bezpečně ignorovat, protože dokument je již zachován.
Nová instance zopakuje kroky a dokončí trvalost, pokud byl předchozí pracovní proces ukončen před tím, než se zapsal do databáze.
Podrobnosti implementace operací čtení
Rozhraní API přímo zpracovává operace čtení a okamžitě vrací data zpět uživateli.
Metoda back-channel není navázána pro komunikaci s klientem, pokud se operace úspěšně dokončí. Klientská aplikace musí proaktivně dotazovat rozhraní API na aktualizace o položce zadané v Location
hlavičce HTTP.
Škálovatelnost
Jednotlivé komponenty úloh by se měly škálovat nezávisle, protože každá komponenta má různé vzory zatížení. Požadavky na škálování závisí na funkčnosti služby. Některé služby přímo ovlivňují uživatele a musí agresivně navýšovat kapacitu, aby se zajistily rychlé odpovědi a pozitivní uživatelské prostředí.
Implementace zabalí služby jako image kontejnerů a pomocí chartů Helm nasadí služby do každého razítka. Služby jsou nakonfigurované tak, aby měly očekávané požadavky a limity Kubernetes a předem nakonfigurované pravidlo automatického škálování. BackgroundProcessor
Komponenty CatalogService
úloh se můžou škálovat a škálovat jednotlivě, protože obě služby jsou bezstavové.
Uživatelé komunikují přímo s touto CatalogService
částí, takže tato část úlohy musí reagovat při jakémkoli zatížení. Pro každý cluster existuje minimálně tři instance, které se mají rozložit mezi tři zóny dostupnosti v oblasti Azure. Horizontální automatické škálování podů (HPA) v AKS automaticky podle potřeby přidává další pody. Funkce automatického škálování služby Azure Cosmos DB může dynamicky zvýšit a snížit počet jednotek žádostí dostupných pro kolekci. Služba CatalogService
Azure Cosmos DB zkombinuje jednotku škálování v rámci razítka.
HpA se nasadí s chartem Helm, který má konfigurovatelný maximální počet a minimální počet replik. Zátěžový test zjistil, že každá instance dokáže zpracovat přibližně 250 požadavků za sekundu se standardním vzorem použití.
Služba BackgroundProcessor
má různé požadavky a považuje se za pracovní proces na pozadí, který má omezený vliv na uživatelské prostředí. Má tedy BackgroundProcessor
v porovnání CatalogService
s jinou konfigurací automatického škálování a může se škálovat mezi 2 a 32 instancemi. Tento limit určete na základě počtu oddílů, které používáte v centrech událostí. Nepotřebujete více pracovních procesů než oddíly.
Komponenta | minReplicas |
maxReplicas |
---|---|---|
CatalogService | 3 | 20 |
BackgroundProcessor | 2 | 32 |
Každá komponenta úlohy, která zahrnuje závislosti, jako ingress-nginx
je, má nakonfigurované nastavení rozpočtů přerušení podů( PDB), aby se zajistilo, že při změně clusterů zůstane k dispozici minimální počet instancí.
Následující blok kódu se zobrazí v referenční implementaci:
#
# /src/app/charts/healthservice/templates/pdb.yaml
# Example pod distribution budget configuration.
#
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: {{ .Chart.Name }}-pdb
spec:
minAvailable: 1
selector:
matchLabels:
app: {{ .Chart.Name }}
Poznámka:
Určení skutečného minimálního počtu a maximálního počtu podů pro každou komponentu prostřednictvím zátěžového testování Počet podů se může pro každou úlohu lišit.
Instrumentace
Instrumentace slouží k vyhodnocení problémů s výkonem lahví a problémů se stavem, které můžou součásti úloh zavést do systému. Aby vám pomohla kvantifikovat rozhodnutí, každá komponenta by měla generovat dostatečné informace prostřednictvím metrik a protokolů trasování. Při instrumentaci aplikace zvažte následující klíčové aspekty:
- Odešle protokoly, metriky a další telemetrii do systému protokolů kolku.
- Místo prostého textu používejte strukturované protokolování, abyste mohli dotazovat informace.
- Implementujte korelaci událostí, abyste získali kompletní zobrazení transakcí. V referenční implementaci obsahuje každá odpověď rozhraní API ID operace jako hlavičku HTTP pro sledovatelnost.
- Nespoléhejte jenom na protokolování stdout ani na protokolování konzoly. Tyto protokoly ale můžete použít k okamžitému řešení potíží s neúspěšným podem.
Tato architektura implementuje distribuované trasování pomocí Application Insights a pracovního prostoru protokolů služby Azure Monitor pro data monitorování aplikací. Protokoly služby Azure Monitor můžete použít pro protokoly a metriky komponent úloh a infrastruktury. Tato architektura implementuje kompletní trasování požadavků přicházejících z rozhraní API, projděte službu Event Hubs a pak do služby Azure Cosmos DB.
Důležité
Nasaďte prostředky monitorování kolku do samostatné skupiny prostředků monitorování. Prostředky mají jiný životní cyklus než samotný kolek. Další informace najdete v tématu Monitorování dat pro prostředky razítka.
Podrobnosti implementace monitorování aplikací
Komponenta BackgroundProcessor
používá Microsoft.ApplicationInsights.WorkerService
balíček NuGet k získání zastaralé instrumentace z aplikace. Serilog se také používá pro veškeré protokolování uvnitř aplikace. Služba Application Insights je kromě jímky konzoly nakonfigurovaná jako jímka. TelemetryClient
Instance pro Application Insights se používá přímo jenom v případě, že je potřeba sledovat další metriky.
Následující blok kódu se zobrazí v referenční implementaci:
//
// /src/app/AlwaysOn.BackgroundProcessor/Program.cs
//
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(hostContext.Configuration)
.Enrich.FromLogContext()
.WriteTo.Console(outputTemplate: "[{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} {Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}")
.WriteTo.ApplicationInsights(hostContext.Configuration[SysConfiguration.ApplicationInsightsConnStringKeyName], TelemetryConverter.Traces)
.CreateLogger();
}
Aby bylo možné předvést praktickou sledovatelnost požadavků, vrátí každý úspěšný a neúspěšný požadavek rozhraní API hlavičku ID korelace volajícímu. Tým podpory aplikace může prohledávat Application Insights pomocí tohoto identifikátoru a získat podrobné zobrazení celé transakce, která je znázorněna v předchozím diagramu.
Následující blok kódu se zobrazí v referenční implementaci:
//
// /src/app/AlwaysOn.CatalogService/Startup.cs
//
app.Use(async (context, next) =>
{
context.Response.OnStarting(o =>
{
if (o is HttpContext ctx)
{
// ... code omitted for brevity
context.Response.Headers.Add("Server-Location", sysConfig.AzureRegion);
context.Response.Headers.Add("Correlation-ID", Activity.Current?.RootId);
context.Response.Headers.Add("Requested-Api-Version", ctx.GetRequestedApiVersion()?.ToString());
}
return Task.CompletedTask;
}, context);
await next();
});
Poznámka:
Adaptivní vzorkování je ve výchozím nastavení povolené v sadě Application Insights SDK. Adaptivní vzorkování znamená, že se do cloudu neodesílají všechny požadavky a dají se prohledávat podle ID. Důležité aplikační týmy potřebují spolehlivě sledovat všechny požadavky, což je důvod, proč má referenční implementace v produkčním prostředí zakázané adaptivní vzorkování.
Podrobnosti o implementaci monitorování Kubernetes
Nastavení diagnostiky můžete použít k odesílání protokolů a metrik AKS do protokolů služby Azure Monitor. Funkci Přehledy kontejnerů můžete použít také s AKS. Povolte službě Container Insights nasazení OMSAgentForLinux prostřednictvím daemonSet Kubernetes na každý uzel v clusterech AKS. OMSAgentForLinux může shromažďovat další protokoly a metriky z clusteru Kubernetes a odesílat je do příslušného pracovního prostoru protokolů služby Azure Monitor. Tento pracovní prostor obsahuje podrobná data o podech, nasazeních, službách a celkovém stavu clusteru.
Rozsáhlé protokolování může negativně ovlivnit náklady a neposkytuje výhody. Z tohoto důvodu jsou pro pody úloh v konfiguraci přehledů kontejnerů zakázané shromažďování protokolů stdout a výstřižky Prometheus, protože všechny trasování jsou už zachycené prostřednictvím Application Insights, což generuje duplicitní záznamy.
Následující blok kódu se zobrazí v referenční implementaci:
#
# /src/config/monitoring/container-azm-ms-agentconfig.yaml
# This is just a snippet showing the relevant part.
#
[log_collection_settings]
[log_collection_settings.stdout]
enabled = false
exclude_namespaces = ["kube-system"]
Další informace najdete v úplném konfiguračním souboru.
Monitorování stavu aplikace
Monitorování a pozorovatelnost aplikací můžete použít k rychlé identifikaci problémů systému a informování modelu stavu o aktuálním stavu aplikace. Monitorování stavu můžete zobrazit prostřednictvím koncových bodů stavu. Sondy stavu používají data monitorování stavu k poskytování informací. Hlavní nástroj pro vyrovnávání zatížení pomocí těchto informací okamžitě vytáčí komponentu, která není v pořádku.
Tato architektura používá monitorování stavu na následujících úrovních:
Pody úloh, které běží v AKS Tyto pody mají sondy stavu a aktivity, takže AKS může spravovat jejich životní cyklus.
Health Service, což je vyhrazená komponenta v clusteru. Služba Azure Front Door je nakonfigurovaná tak, aby testovala službu Health Service v každém kolku a odebrala kolky, které nejsou v pořádku, z automatického vyrovnávání zatížení.
Podrobnosti implementace služby Health Service
HealthService
je komponenta úlohy, která běží společně s dalšími komponentami, například CatalogService
a BackgroundProcessor
, ve výpočetním clusteru. HealthService
poskytuje rozhraní REST API, které volání kontroly stavu služby Azure Front Door určují dostupnost razítka. Na rozdíl od základních sond živé aktivity je služba Health Service složitější komponentou, která kromě vlastního stavu poskytuje stav závislostí.
Služba Health Service nereaguje, pokud je cluster AKS nefunkční, což vykreslí úlohu, která není v pořádku. Když služba běží, provádí pravidelné kontroly kritických součástí řešení. Všechny kontroly se provádějí asynchronně a paralelně. Pokud některá z kontrol selže, celé razítko není k dispozici.
Upozorňující
Sondy stavu služby Azure Front Door můžou výrazně zatížit službu Health Service, protože požadavky pocházejí z několika míst přítomnosti (PoP). Pokud chcete zabránit přetížení podřízených komponent, implementujte efektivní ukládání do mezipaměti.
Služba Health Service se také používá pro explicitně nakonfigurované testy ping adresy URL s prostředkem Application Insights každého razítka.
Další informace o implementaci naleznete v HealthService
tématu Application Health Service.