Ontwerpen voor zelfherstel
De toepassing zo ontwerpen dat zelfherstel mogelijk is wanneer er fouten optreden
In een gedistribueerd systeem moeten fouten worden verwacht. De hardware kan defect raken. Het netwerk kan tijdelijke storingen ondervinden. Zelden ondervindt een hele service, datacentrum of zelfs Azure-regio een onderbreking, maar zelfs die moeten worden ontworpen voor in uw workloadarchitectuur. Tolerantie en herstel moeten vroeg in uw workloadontwerp worden aangepakt.
Ontwerp daarom een toepassing die zichzelf herstelt wanneer er fouten optreden. Hiervoor is een drieledige methode vereist:
- Detecteren van fouten.
- Probleemloos reageren op fouten.
- Logboek- en monitorfouten om operationeel inzicht te geven.
Hoe u op een bepaald type fout reageert, is afhankelijk van de beschikbaarheidsvereisten van uw toepassing. Als u bijvoorbeeld hoge beschikbaarheid nodig hebt, kunt u implementeren in meerdere beschikbaarheidszones in een regio. Om storingen te voorkomen, zelfs in het onwaarschijnlijke geval van een hele Azure-regio die onderbrekingen ondervindt, kunt u automatisch een failover naar een secundaire regio uitvoeren tijdens een regionale storing. Dit leidt echter tot hogere kosten en mogelijk lagere prestaties dan een implementatie met één regio.
Focus u bovendien niet te veel op grote gebeurtenissen, zoals regionale onderbrekingen, omdat deze over het algemeen niet veel voorkomen. Richt u minstens zoveel op het verwerken van lokale fouten van kortere duur, zoals fouten in de netwerkconnectiviteit of mislukte databaseverbindingen.
Aanbevelingen
Losgekoppelde onderdelen gebruiken die asynchroon communiceren. In het ideale opzicht worden onderdelen losgekoppeld in termen van tijd en ruimte. Ontkoppeld in tijd betekent dat onderdelen niet tegelijkertijd aanwezig hoeven te zijn om communicatie mogelijk te maken. Losgekoppeld in de ruimte betekent dat de afzender en ontvanger niet hoeven te worden uitgevoerd in hetzelfde proces, maar ze kunnen waar het ook efficiënter is. Losgekoppelde onderdelen maken idealiter gebruik van gebeurtenissen om met elkaar te communiceren. Dit helpt de kans op trapsgewijze fouten te minimaliseren.
Voer mislukte bewerkingen opnieuw uit. Tijdelijke fouten kunnen optreden als gevolg van tijdelijk verlies van netwerkverbinding, een verbroken databaseverbinding of een time-out wanneer een service bezet is. Bouw pogingslogica in de toepassing in om tijdelijke fouten te verwerken. Bij veel Azure-services worden met de client SDK automatische nieuwe pogingen geïmplementeerd. Zie Tijdelijke foutafhandeling en het patroon Opnieuw proberen voor meer informatie.
Beveilig niet goed werkende externe services (Circuitonderbreker). Het is een goed idee om een nieuwe poging uit te voeren na een tijdelijke fout, maar als de fout zich blijft voordoen, kan het voorkomen dat er te veel aanroepen worden gedaan bij een niet goed werkende service. Dit kan leiden tot trapsgewijze fouten als er een back-up van aanvragen wordt uitgevoerd. Gebruik het circuitonderbrekerpatroon om snel te mislukken (zonder de externe aanroep te doen) wanneer een bewerking waarschijnlijk mislukt.
Isoleer kritieke resources (Bulkhead). Fouten in één subsysteem kunnen zich soms opstapelen. Dit kan gebeuren als een fout tot gevolg heeft dat sommige resources, zoals threads of sockets, niet tijdig worden vrijgemaakt, wat leidt tot uitputting van resources. Om dit te voorkomen, gebruikt u het schotpatroon om een systeem te partitioneren in geïsoleerde groepen, zodat een fout in één partitie het hele systeem niet naar beneden haalt.
Voer load leveling uit. Toepassingen kunnen plotselinge pieken in het verkeer ervaren die services op de back-end kunnen overbelasten. Om dit te voorkomen, gebruikt u het patroon Load Leveling op basis van wachtrij om werkitems in de wachtrij te plaatsen om asynchroon uit te voeren. De wachtrij fungeert als een buffer die de pieken in de werkbelasting afvlakt.
Voer een failover uit. Als een instantie niet kan worden bereikt, kunt u een failover uitvoeren naar een andere instantie. Voor staatloze items, zoals een webserver, plaatst u meerdere instanties achter een load balancer of Traffic Manager. Gebruik replica’s en failover voor items die een status hebben, zoals een database. Afhankelijk van het gegevensarchief en hoe deze wordt gerepliceerd, moet de toepassing mogelijk te maken krijgen met uiteindelijke consistentie.
Compenseer mislukte transacties. Over het algemeen wordt het aangeraden om gedistribueerde transacties te voorkomen, omdat hiervoor coördinatie tussen verschillende services en resources is vereist. Gebruik in plaats hiervan een bewerking die bestaat uit kleinere afzonderlijke transacties. Als de bewerking halverwege mislukt, gebruikt u Compensatietransacties om alle reeds voltooide stappen ongedaan te maken.
Controlepunt bij langlopende transacties. Controlepunten kunnen flexibiliteit bieden als een langdurige bewerking mislukt. Wanneer de bewerking opnieuw wordt gestart (bijvoorbeeld wanneer deze wordt voortgezet op een andere VM), kan deze worden hervat vanaf het laatste controlepunt. Overweeg om een mechanisme te implementeren waarmee statusinformatie over de taak regelmatig wordt vastgelegd en deze status opslaat in duurzame opslag die toegankelijk is voor elk exemplaar van het proces dat de taak uitvoert. Als het proces op deze manier wordt afgesloten, kan het werk dat het proces heeft uitgevoerd, worden hervat vanaf het laatste controlepunt met behulp van een ander exemplaar. Er zijn bibliotheken die deze functionaliteit bieden, zoals NServiceBus en MassTransit. Ze behouden de status transparant, waarbij de intervallen worden afgestemd op de verwerking van berichten uit wachtrijen in Azure Service Bus.
Degradeer probleemloos en blijf responsief tijdens fouten. Soms is er geen tijdelijke oplossing voor een probleem. U kunt dan echter wel een verminderde functionaliteit bieden die nog steeds nuttig is. Neem als voorbeeld een toepassing met een boekencatalogus. Als de toepassing de miniatuurafbeelding voor het omslag niet kan ophalen, dan kan er tijdelijk een vervangende afbeelding worden getoond. Volledige subsystemen zijn mogelijk niet-kritiek voor de toepassing. Op een e-commercesite is bijvoorbeeld het weergeven van productaanbeveling waarschijnlijk minder kritiek dan het verwerken van orders.
Beperk klanten. Soms zorgt een klein aantal gebruikers voor een overmatige werkbelasting. Dit kan de beschikbaarheid van de toepassing verminderen voor andere gebruikers. Beperk deze klanten in dit geval gedurende een bepaalde tijdsperiode. Zie het patroon Beperking.
Blokkeer ongeldige actoren. Als u een klant beperkt, betekent dit niet dat deze zich heeft misdragen. Het betekent alleen dat de klant zijn/haar servicequotum heeft overschreden. Maar als een klant consequent dit quotum overschrijdt of ander ongewenst gedrag vertoont, kunt u ervoor kiezen de klant te blokkeren. Definieer een buiten-bandproces waarmee de gebruiker kan aanvragen om de blokkering op te heffen.
Gebruik Selectie van leider. Gebruik Selectie van leider om een coördinator te selecteren, wanneer u een taak hebt die moet worden gecoördineerd. Op deze manier is de coördinator geen SPOF (Single Point of Failure). Als de coördinator niet slaagt, wordt er een nieuwe geselecteerd. Overweeg om een gebruiksklare oplossing te gebruiken, zoals Zookeeper, in plaats van een heel nieuw algoritme voor het selecteren van een leider te implementeren.
Test met foutinjectie. Het komt maar al te vaak voor dat de successen goed zijn getest, maar de fouten niet. Een systeem kan al lange tijd in productie zijn voordat als oefening een fout wordt uitgevoerd. Gebruik foutinjectie om de flexibiliteit van het systeem tijdens storingen te testen door echte storingen te activeren of door ze te simuleren.
Profiteer van chaos-engineering. Chaos engineering breidt het begrip foutinjectie uit door willekeurig fouten of abnormale omstandigheden in productie-exemplaren te injecteren.
Gebruik beschikbaarheidszones. Veel Azure-regio's bieden beschikbaarheidszones, die geïsoleerde sets datacenters binnen de regio zijn. Sommige Azure-services kunnen zonegebonden worden geïmplementeerd, zodat ze in een specifieke zone worden geplaatst en kunnen helpen de latentie te verminderen bij de communicatie tussen onderdelen in dezelfde workload. Sommige services kunnen ook worden geïmplementeerd met zoneredundantie, wat betekent dat Azure de resource automatisch repliceert tussen zones voor hoge beschikbaarheid. Bedenk welke benadering de beste set compromissen biedt voor uw oplossing. Zie Aanbevelingen voor het gebruik van beschikbaarheidszones en -regio's voor meer informatie over het ontwerpen van uw oplossing voor het gebruik van beschikbaarheidszones en -regio's.
Zie Betrouwbare toepassingen ontwerpen voor Azure voor een gestructureerde aanpak om uw toepassingen zelfherstel te maken.