Delen via


Toepassingsontwerp van bedrijfskritieke workloads in Azure

Wanneer u een toepassing ontwerpt, zijn zowel functionele als niet-functionele toepassingsvereisten essentieel. In dit ontwerpgebied worden architectuurpatronen en schaalstrategieën beschreven waarmee uw toepassing bestand kan worden tegen fouten.

Belangrijk

Dit artikel maakt deel uit van de azure Well-Architected Framework-serie bedrijfskritieke workload . Als u niet bekend bent met deze reeks, raden we u aan te beginnen met Wat is een bedrijfskritieke workload?

Architectuur voor schaaleenheden

Alle functionele aspecten van een oplossing moeten kunnen worden geschaald om te voldoen aan veranderingen in de vraag. U wordt aangeraden een architectuur voor schaaleenheden te gebruiken om de end-to-end schaalbaarheid te optimaliseren door middel van compartimentalisering en om het proces voor het toevoegen en verwijderen van capaciteit te standaardiseren. Een schaaleenheid is een logische eenheid of functie die onafhankelijk kan worden geschaald. Een eenheid kan bestaan uit codeonderdelen, hostingplatforms voor toepassingen, de implementatiestempels die betrekking hebben op de gerelateerde onderdelen en zelfs abonnementen ter ondersteuning van vereisten voor meerdere tenants .

We raden deze aanpak aan omdat hiermee de schaallimieten van afzonderlijke resources en de hele toepassing worden aangepakt. Het helpt bij complexe implementatie- en updatescenario's, omdat een schaaleenheid kan worden geïmplementeerd als één eenheid. U kunt ook specifieke versies van onderdelen in een eenheid testen en valideren voordat u gebruikersverkeer naar deze eenheid leidt.

Stel dat uw bedrijfskritieke toepassing een online productcatalogus is. Het heeft een gebruikersstroom voor het verwerken van productopmerkingen en beoordelingen. De stroom maakt gebruik van API's om opmerkingen en beoordelingen op te halen en te posten, en ondersteunende onderdelen zoals een OAuth-eindpunt, gegevensopslag en berichtenwachtrijen. De stateless API-eindpunten vertegenwoordigen gedetailleerde functionele eenheden die moeten worden aangepast aan wijzigingen op aanvraag. Het onderliggende toepassingsplatform moet ook dienovereenkomstig kunnen worden geschaald. Om prestatieknelpunten te voorkomen, moeten de downstreamonderdelen en afhankelijkheden ook worden geschaald naar een geschikte mate. Ze kunnen onafhankelijk schalen, als afzonderlijke schaaleenheden of samen, als onderdeel van één logische eenheid.

Voorbeeld van schaaleenheden

In de volgende afbeelding ziet u de mogelijke bereiken voor schaaleenheden. De bereiken variëren van microservicepods tot clusterknooppunten en regionale implementatiestempels.

Diagram met meerdere bereiken voor schaaleenheden.

Ontwerpoverwegingen

  • Bereik. Het bereik van een schaaleenheid, de relatie tussen schaaleenheden en de bijbehorende onderdelen moet worden gedefinieerd volgens een capaciteitsmodel. Neem rekening met niet-functionele vereisten voor prestaties.

  • Schaallimieten. Schaallimieten en quota voor Azure-abonnementen hebben mogelijk invloed op het ontwerp van toepassingen, technologiekeuzen en de definitie van schaaleenheden. Met schaaleenheden kunt u de schaallimieten van een service omzeilen. Als een AKS-cluster in één eenheid bijvoorbeeld slechts 1000 knooppunten kan hebben, kunt u twee eenheden gebruiken om die limiet te verhogen tot 2000 knooppunten.

  • Verwachte belasting. Gebruik het aantal aanvragen voor elke gebruikersstroom, de verwachte piekaanvraagsnelheid (aanvragen per seconde) en dagelijkse/wekelijkse/seizoensverkeerspatronen om de belangrijkste vereisten voor schaalaanpassing te informeren. Houd ook rekening met de verwachte groeipatronen voor zowel verkeer als gegevensvolume.

  • Acceptabele gedegradeerde prestaties. Bepaal of een gedegradeerde service met hoge reactietijden acceptabel is onder belasting. Wanneer u de vereiste capaciteit modelleert, is de vereiste prestaties van de oplossing onder belasting een kritieke factor.

  • Niet-functionele vereisten. Technische en bedrijfsscenario's hebben verschillende overwegingen voor tolerantie, beschikbaarheid, latentie, capaciteit en waarneembaarheid. Analyseer deze vereisten in de context van belangrijke end-to-endgebruikersstromen. U hebt relatieve flexibiliteit in het ontwerp, de besluitvorming en de technologische keuzes op gebruikersstroomniveau.

Ontwerpaanaanvelingen

  • Definieer het bereik van een schaaleenheid en de limieten waarmee de eenheid wordt geschaald.

  • Zorg ervoor dat alle toepassingsonderdelen onafhankelijk kunnen worden geschaald of als onderdeel van een schaaleenheid die andere gerelateerde onderdelen bevat.

  • Definieer de relatie tussen schaaleenheden op basis van een capaciteitsmodel en niet-functionele vereisten.

  • Definieer een regionale implementatiestempel om de inrichting, het beheer en de werking van regionale toepassingsresources te combineren in een heterogene maar onderling afhankelijke schaaleenheid. Naarmate de belasting toeneemt, kunnen er extra stempels binnen dezelfde Azure-regio of verschillende worden geïmplementeerd om de oplossing horizontaal te schalen.

  • Gebruik een Azure-abonnement als schaaleenheid, zodat schaallimieten binnen één abonnement de schaalbaarheid niet beperken. Deze benadering is van toepassing op grootschalige toepassingsscenario's met een aanzienlijk verkeersvolume.

  • Model vereist capaciteit rond geïdentificeerde verkeerspatronen om ervoor te zorgen dat voldoende capaciteit wordt ingericht op piekmomenten om servicedegradatie te voorkomen. U kunt de capaciteit ook optimaliseren tijdens daluren.

  • Meet de tijd die nodig is om uit- en inschaalbewerkingen uit te voeren om ervoor te zorgen dat de natuurlijke variaties in het verkeer geen onaanvaardbaar servicedegradatieniveau creëren. Houd de duur van de schaalbewerking bij als een operationele metrische waarde.

Notitie

Wanneer u implementeert in een Azure-landingszone, moet u ervoor zorgen dat het abonnement op de landingszone is toegewezen aan de toepassing om een duidelijke beheergrens te bieden en om antipatroon van Noisy Neighbor te voorkomen.

Wereldwijde distributie

Het is onmogelijk om fouten in een zeer gedistribueerde omgeving te voorkomen. Deze sectie bevat strategieën voor het beperken van veel foutscenario's. De toepassing moet bestand zijn tegen regionale en zonegebonden storingen. Het moet worden geïmplementeerd in een actief/actief model, zodat de belasting wordt verdeeld over alle regio's.

Bekijk deze video voor een overzicht van het plannen van fouten in bedrijfskritieke toepassingen en het maximaliseren van tolerantie:

Ontwerpoverwegingen

  • Redundantie. Uw toepassing moet worden geïmplementeerd in meerdere regio's. Daarnaast raden we u in een regio ten zeerste aan om beschikbaarheidszones te gebruiken om fouttolerantie op datacenterniveau mogelijk te maken. Beschikbaarheidszones hebben een latentieperimeter van minder dan 2 milliseconden tussen beschikbaarheidszones. Voor workloads die 'chatty' tussen zones zijn, kan deze latentie een prestatiestraf voor interzonegegevensoverdracht veroorzaken.

  • Actief/actief model. Een actieve/actieve implementatiestrategie wordt aanbevolen omdat deze de beschikbaarheid maximaliseert en een hogere sla (Service Level Agreement) biedt. Het kan echter problemen veroorzaken met gegevenssynchronisatie en consistentie voor veel toepassingsscenario's. Los de uitdagingen op gegevensplatformniveau aan terwijl u rekening houdt met de afwegingen van verhoogde kosten en technische inspanningen.

    Een actieve/actieve implementatie tussen meerdere cloudproviders is een manier om de afhankelijkheid van wereldwijde resources binnen één cloudprovider mogelijk te beperken. Een strategie voor actieve/actieve implementatie met meerdere clouds introduceert echter een aanzienlijke mate van complexiteit rond CI/CD. Gezien de verschillen in resourcespecificaties en -mogelijkheden tussen cloudproviders, hebt u speciale implementatiestempels nodig voor elke cloud.

  • Geografische verdeling. De workload heeft mogelijk nalevingsvereisten voor geografische gegevenslocatie, gegevensbescherming en gegevensretentie. Overweeg of er specifieke regio's zijn waar gegevens moeten worden opgeslagen of waar resources moeten worden geïmplementeerd.

  • Oorsprong aanvragen. De geografische nabijheid en dichtheid van gebruikers of afhankelijke systemen moeten ontwerpbeslissingen over wereldwijde distributie informeren.

  • Connectiviteit. Hoe de workload wordt geopend door gebruikers of externe systemen, heeft invloed op uw ontwerp. Overweeg of de toepassing beschikbaar is via het openbare internet of particuliere netwerken die gebruikmaken van VPN- of Azure ExpressRoute-circuits.

Zie Toepassingsplatform: wereldwijde distributie voor aanbevelingen en configuratieopties op platformniveau.

Losjes gekoppelde gebeurtenisgestuurde architectuur

Koppeling maakt communicatie tussen services mogelijk via goed gedefinieerde interfaces. Met een losse koppeling kan een toepassingsonderdeel onafhankelijk van elkaar werken. Een architectuurstijl voor microservices is consistent met essentiële vereisten. Het vereenvoudigt hoge beschikbaarheid door trapsgewijze fouten te voorkomen.

Voor losse koppeling raden we u ten zeerste aan om gebeurtenisgestuurd ontwerp op te nemen. Asynchrone berichtverwerking via een intermediair kan tolerantie opbouwen.

Diagram dat asynchrone gebeurtenisgestuurde communicatie illustreert.

In sommige scenario's kunnen toepassingen losse en strakke koppeling combineren, afhankelijk van bedrijfsdoelstellingen.

Ontwerpoverwegingen

  • Runtime-afhankelijkheden. Losjes gekoppelde services mogen niet worden beperkt tot het gebruik van hetzelfde rekenplatform, dezelfde programmeertaal, runtime of besturingssysteem.

  • Schalen. Services moeten onafhankelijk kunnen worden geschaald. Optimaliseer het gebruik van infrastructuur- en platformbronnen.

  • Fouttolerantie. Fouten moeten afzonderlijk worden verwerkt en mogen geen invloed hebben op clienttransacties.

  • Transactionele integriteit. Houd rekening met het effect van het maken en persistentie van gegevens die in afzonderlijke services plaatsvinden.

  • Gedistribueerde tracering. End-to-end tracering vereist mogelijk complexe indeling.

Ontwerpaanaanvelingen

  • De grenzen van microservices afstemmen met kritieke gebruikersstromen.

  • Gebruik waar mogelijk gebeurtenisgestuurde asynchrone communicatie om duurzame schaal en optimale prestaties te ondersteunen.

  • Gebruik patronen zoals Postvak UIT en Transactionele sessie om consistentie te garanderen, zodat elk bericht correct wordt verwerkt.

Voorbeeld: Gebeurtenisgestuurde benadering

De mission-Critical Online-referentie-implementatie maakt gebruik van microservices om één zakelijke transactie te verwerken. Schrijfbewerkingen worden asynchroon toegepast met een berichtenbroker en -werkrol. Leesbewerkingen zijn synchroon, waarbij het resultaat rechtstreeks naar de aanroeper wordt geretourneerd.

Diagram met gebeurtenisgestuurde communicatie.

Tolerantiepatronen en foutafhandeling in toepassingscode

Een bedrijfskritieke toepassing moet zo zijn ontworpen dat deze flexibel is, zodat er zoveel mogelijk foutscenario's worden opgelost. Deze tolerantie maximaliseert de beschikbaarheid en betrouwbaarheid van de service. De toepassing moet zelfherstelmogelijkheden hebben, die u kunt implementeren met behulp van ontwerppatronen zoals Nieuwe pogingen met Backoff en CircuitOnderbreker.

Voor niet-tijdelijke fouten die u niet volledig kunt beperken in toepassingslogica, moeten het statusmodel en de operationele wrappers corrigerende maatregelen nemen. Toepassingscode moet de juiste instrumentatie en logboekregistratie bevatten om het statusmodel te informeren en de volgende probleemoplossing of hoofdoorzaakanalyse mogelijk te maken, indien nodig. U moet gedistribueerde tracering implementeren om de aanroeper een uitgebreid foutbericht te bieden dat een correlatie-id bevat wanneer er een fout optreedt.

Hulpprogramma's zoals Application Insights kunnen u helpen bij het opvragen, correleren en visualiseren van toepassingstraceringen.

Ontwerpoverwegingen

  • Juiste configuraties. Het is niet ongebruikelijk dat tijdelijke problemen trapsgewijze fouten veroorzaken. Probeer het bijvoorbeeld opnieuw zonder de juiste back-off het probleem te verergeren wanneer een service wordt beperkt. U kunt vertragingen voor opnieuw proberen lineair ruimte geven of ze exponentieel verhogen om terug te keren door groeiende vertragingen.

  • Statuseindpunten. U kunt functionele controles in toepassingscode beschikbaar maken met behulp van statuseindpunten die externe oplossingen kunnen peilen om de status van toepassingsonderdelen op te halen.

Ontwerpaanaanvelingen

Hier volgen enkele algemene software-engineeringpatronen voor tolerante toepassingen:

Patroon Samenvatting
Load Leveling op basis van wachtrij Introduceert een buffer tussen consumenten en aangevraagde resources om consistente belastingniveaus te garanderen. Wanneer consumentenaanvragen in de wachtrij worden geplaatst, verwerkt een werkproces deze op basis van de aangevraagde resource in een tempo dat is ingesteld door de werkrol en door de mogelijkheid van de aangevraagde resource om de aanvragen te verwerken. Als consumenten verwachten dat ze antwoorden op hun aanvragen verwachten, moet u een afzonderlijk antwoordmechanisme implementeren. Pas een volgorde met prioriteit toe, zodat de belangrijkste activiteiten eerst worden uitgevoerd.
Circuitonderbreker Biedt stabiliteit door te wachten op herstel of aanvragen snel te weigeren in plaats van te blokkeren terwijl wordt gewacht op een niet-beschikbare externe service of resource. Dit patroon verwerkt ook fouten die mogelijk een variabele tijd in beslag nemen om te herstellen wanneer een verbinding wordt gemaakt met een externe service of resource.
Bulkhead Pogingen om service-exemplaren te partitioneren in groepen op basis van belastings- en beschikbaarheidsvereisten, die fouten isoleren om de servicefunctionaliteit te ondersteunen.
Saga Beheert gegevensconsistentie tussen microservices die onafhankelijke gegevensarchieven hebben door ervoor te zorgen dat services elkaar bijwerken via gedefinieerde gebeurtenis- of berichtkanalen. Elke service voert lokale transacties uit om zijn eigen status bij te werken en publiceert een gebeurtenis om de volgende lokale transactie in de saga te activeren. Als een service-update mislukt, voert de saga compenserende transacties uit om voorgaande service-updatestappen tegen te gaan. Afzonderlijke stappen voor het bijwerken van services kunnen zelf tolerantiepatronen implementeren, zoals opnieuw proberen.
Eindpuntstatusbewaking Implementeert functionele controles in een toepassing waartoe externe hulpprogramma's met regelmatige tussenpozen toegang hebben via blootgestelde eindpunten. U kunt reacties van de eindpunten interpreteren met behulp van belangrijke operationele metrische gegevens om de toepassingsstatus te informeren en operationele antwoorden te activeren, zoals het genereren van een waarschuwing of het uitvoeren van een compenserende implementatie voor terugdraaien.
Opnieuw proberen Behandelt tijdelijke fouten elegant en transparant.
- Annuleren als de fout waarschijnlijk niet tijdelijk is en waarschijnlijk niet slaagt als de bewerking opnieuw wordt geprobeerd.
- Probeer het opnieuw als de fout ongebruikelijk of zeldzaam is en de bewerking waarschijnlijk slaagt als de bewerking onmiddellijk opnieuw wordt geprobeerd.
- Probeer het opnieuw na een vertraging als de fout wordt veroorzaakt door een voorwaarde die mogelijk een korte tijd nodig heeft om te herstellen, zoals netwerkconnectiviteit of fouten met een hoge belasting. Pas een geschikte back-off-strategie toe naarmate vertragingen voor nieuwe pogingen toenemen.
Beperking Hiermee bepaalt u het verbruik van resources die door toepassingsonderdelen worden gebruikt, zodat u ze niet te veel kunt beschermen. Wanneer een resource een belastingsdrempel bereikt, worden bewerkingen met een lagere prioriteit uitgesteld en wordt de niet-essentiële functionaliteit verminderd, zodat essentiële functionaliteit kan worden voortgezet totdat er voldoende resources beschikbaar zijn om terug te keren naar de normale werking.

Hier volgen enkele aanvullende aanbevelingen:

  • Gebruik door de leverancier geleverde SDK's, zoals de Azure SDK's, om verbinding te maken met afhankelijke services. Ingebouwde tolerantiemogelijkheden gebruiken in plaats van aangepaste functionaliteit te implementeren.

  • Pas een geschikte back-offstrategie toe wanneer u mislukte afhankelijkheidsaanroepen opnieuw probeert uit te voeren om een DDoS-scenario dat zelf is toegebracht, te voorkomen.

  • Definieer algemene technische criteria voor alle microserviceteams van toepassingen om consistentie en snelheid te stimuleren bij het gebruik van tolerantiepatronen op toepassingsniveau.

  • Implementeer tolerantiepatronen met behulp van bewezen gestandaardiseerde pakketten, zoals Polly voor C# of Sentinel voor Java.

  • Gebruik correlatie-id's voor alle traceringsgebeurtenissen en logboekberichten om deze te koppelen aan een bepaalde aanvraag. Retourneer correlatie-id's naar de beller voor alle oproepen, niet alleen mislukte aanvragen.

  • Gebruik gestructureerde logboekregistratie voor alle logboekberichten. Selecteer een geïntegreerde sink voor operationele gegevens voor toepassingstraceringen, metrische gegevens en logboeken, zodat operators eenvoudig problemen kunnen opsporen. Zie Bewakingsgegevens verzamelen, aggregeren en opslaan voor cloudtoepassingen voor meer informatie.

  • Zorg ervoor dat operationele gegevens samen met bedrijfsvereisten worden gebruikt om een toepassingsstatusmodel te informeren.

Selectie van programmeertaal

Het is belangrijk om de juiste programmeertalen en frameworks te selecteren. Deze beslissingen worden vaak aangestuurd door de vaardighedensets of gestandaardiseerde technologieën in de organisatie. Het is echter essentieel om de prestaties, tolerantie en algemene mogelijkheden van verschillende talen en frameworks te evalueren.

Ontwerpoverwegingen

  • Mogelijkheden van developmentkits. Er zijn verschillen in de mogelijkheden die worden aangeboden door Azure-service-SDK's in verschillende talen. Deze verschillen kunnen van invloed zijn op uw keuze van een Azure-service of programmeertaal. Als Azure Cosmos DB bijvoorbeeld een haalbare optie is, is Go mogelijk geen geschikte ontwikkeltaal omdat er geen externe SDK is.

  • Functie-updates. Bedenk hoe vaak de SDK wordt bijgewerkt met nieuwe functies voor de geselecteerde taal. Veelgebruikte SDK's, zoals .NET- en Java-bibliotheken, worden regelmatig bijgewerkt. Andere SDK's of SDK's voor andere talen kunnen minder vaak worden bijgewerkt.

  • Meerdere programmeertalen of frameworks. U kunt meerdere technologieën gebruiken ter ondersteuning van verschillende samengestelde workloads. U moet echter sprawl vermijden omdat het beheercomplexiteit en operationele uitdagingen introduceert.

  • Berekeningsoptie. Verouderde of bedrijfseigen software wordt mogelijk niet uitgevoerd in PaaS-services. Het is ook mogelijk dat u geen verouderde of bedrijfseigen software in containers kunt opnemen.

Ontwerpaanaanvelingen

  • Evalueer alle relevante Azure SDK's voor de mogelijkheden die u nodig hebt en de gekozen programmeertalen. Controleer de uitlijning met niet-functionele vereisten.

  • Optimaliseer de selectie van programmeertalen en frameworks op microserviceniveau. Gebruik waar nodig meerdere technologieën.

  • Geef prioriteit aan de .NET SDK om de betrouwbaarheid en prestaties te optimaliseren. .NET Azure SDK's bieden doorgaans meer mogelijkheden en worden regelmatig bijgewerkt.

Volgende stap

Bekijk de overwegingen voor het toepassingsplatform.