Behandeln vorübergehender Fehler

Alle Anwendungen, die mit Remotediensten und Ressourcen kommunizieren, müssen gegenüber vorübergehenden Fehlern empfindlich sein. Das gilt insbesondere für Anwendungen, die in der Cloud ausgeführt werden, da bei ihnen derartige Fehler aufgrund der Beschaffenheit der Umgebung und aufgrund der Konnektivität über das Internet häufiger auftreten können. Vorübergehende Fehler umfassen den vorübergehenden Verlust der Netzwerkkonnektivität mit Komponenten und Diensten, die vorübergehende Nichtverfügbarkeit eines Diensts sowie Timeouts, die auftreten, wenn ein Dienst ausgelastet ist. Diese Fehler werden oft automatisch behoben. Wenn der Vorgang also nach einer angemessenen Verzögerung wiederholt wird, ist er wahrscheinlich erfolgreich.

Dieser Artikel enthält einen allgemeinen Leitfaden zur Behandlung vorübergehender Fehler. Informationen zur Behandlung vorübergehender Fehler bei Verwendung von Azure-Diensten finden Sie in der Wiederholungsanleitung für Azure-Dienste.

Warum treten vorübergehende Fehler in der Cloud auf?

Vorübergehende Fehler können in jeder Umgebung auf jeder Plattform und jedem Betriebssystem und bei jeder Anwendung auftreten. Bei Lösungen, die in einer lokalen Infrastruktur ausgeführt werden, werden Leistung und Verfügbarkeit der Anwendung und ihrer Komponenten in der Regel durch teure und häufig zu selten genutzte Hardwareredundanz gewährleistet, und die Komponenten und Ressourcen befinden sich nah beieinander. Dieser Ansatz verringert zwar die Wahrscheinlichkeit von Fehlern, vorübergehende Fehler können jedoch weiterhin auftreten. Gleiches gilt für Ausfälle aufgrund von unvorhergesehenen Ereignissen – etwa Probleme mit der externen Stromversorgung oder dem Netzwerk und andere Notfallszenarien.

Cloudhosting, einschließlich privater Cloudsysteme, kann eine höhere allgemeine Verfügbarkeit bieten, und zwar durch Verwenden gemeinsamer Ressourcen, Redundanz, automatisches Failover und dynamische Zuordnung von Ressourcen über viele herkömmliche Computeknoten. Die Beschaffenheit von Cloudumgebungen macht vorübergehende Fehler wahrscheinlicher. Dafür gibt es mehrere Gründe:

  • Viele Ressourcen in einer Cloudumgebung werden gemeinsam genutzt, und der Zugriff auf diese Ressourcen wird ggf. gedrosselt, um die Ressourcen zu schützen. Wenn die Auslastung ein bestimmtes Niveau erreicht oder eine maximale Durchsatzrate erreicht wird, werden Verbindungen von einigen Diensten abgelehnt, um die Verarbeitung bereits vorhandener Anforderungen zu ermöglichen und die Leistung des Diensts für alle Benutzer zu wahren. Die Drosselung trägt dazu bei, die Qualität des Dienstes für Nachbarn und andere Mandanten, die die freigegebene Ressource nutzen, beizubehalten.

  • In Cloudumgebungen werden zahlreiche herkömmliche Hardwareeinheiten genutzt. Sie stellen Leistung bereit, indem sie die Last dynamisch auf mehrere Recheneinheiten und Infrastrukturkomponenten verteilen. Und sie bieten Zuverlässigkeit, indem sie fehlerhafte Einheiten automatisch recyceln oder austauschen. Aufgrund dieser Dynamik können gelegentlich vorübergehende Fehler und temporäre Verbindungsfehler auftreten.

  • Zwischen der Anwendung und den von ihr verwendeten Ressourcen und Diensten befinden sich häufig weitere Hardwarekomponenten – beispielsweise Netzwerkinfrastrukturkomponenten wie Router und Lastenausgleichsmodule. Diese zusätzliche Infrastruktur kann gelegentlich zu zusätzlicher Verbindungslatenz und vorübergehenden Verbindungsfehlern führen.

  • Die Netzwerkbedingungen zwischen Client und Server sind möglicherweise variabel. Das gilt insbesondere, wenn die Kommunikation über das Internet abläuft. Auch an lokalen Standorten kann eine hohe Datenverkehrsauslastung die Kommunikation verlangsamen und zu zeitweiligen Verbindungsfehlern führen.

Herausforderungen

Vorübergehende Fehler können erhebliche Auswirkungen auf die wahrgenommene Verfügbarkeit einer Anwendung haben, selbst wenn diese unter allen vorhersehbaren Umständen gründlich getestet wurde. Damit in der Cloud gehostete Anwendungen zuverlässig funktionieren, müssen sie mit folgenden Herausforderungen zurechtkommen:

  • Die Anwendung muss in der Lage sein, Fehler zu erkennen, sobald diese auftreten, und bestimmen können, ob diese Fehler eher vorübergehende, lang andauernde oder schwerwiegende Fehler sind. Verschiedene Ressourcen geben wahrscheinlich unterschiedliche Antworten zurück, wenn ein Fehler auftritt, und diese Antworten können auch je nach Kontext des Vorgangs variieren. Beispielsweise kann sich die Antwort bei einem Fehler beim Lesen aus dem Speicher von einer Antwort bei einem Fehler beim Schreiben in den Speicher unterscheiden. Viele Ressourcen und Dienste verfügen über gut dokumentierte Verträge für vorübergehende Fehler. Ohne derartige Informationen lässt sich jedoch möglicherweise nur schwer ermitteln, um welche Art von Fehler es sich handelt und ob er wahrscheinlich vorübergehend ist.

  • Die Anwendung muss in der Lage sein, den Vorgang zu wiederholen, wenn festgestellt wird, dass der Fehler wahrscheinlich vorübergehend ist. Außerdem muss sie die Anzahl von Wiederholungsversuchen für den Vorgang nachverfolgen.

  • Die Anwendung muss eine geeignete Wiederholungsstrategie verwenden. Diese Strategie gibt die Anzahl von Wiederholungsversuchen, die Verzögerung zwischen den einzelnen Versuchen sowie die Aktionen an, die nach jedem nicht erfolgreichen Versuch ausgeführt werden sollen. Die angemessene Anzahl von Versuchen und die Verzögerung zwischen den einzelnen Versuchen sind oft schwierig zu bestimmen. Die Strategie variiert je nach Art der Ressource sowie abhängig von den aktuellen Betriebsbedingungen der Ressource und der Anwendung.

Allgemeine Richtlinien

Die folgenden Richtlinien können Ihnen dabei helfen, für Ihre Anwendungen geeignete Mechanismen zum Behandeln von vorübergehenden Fehlern zu entwerfen:

Ermitteln, ob ein integrierter Wiederholungsmechanismus vorhanden ist

  • Viele Dienste bieten eine SDK oder Client-Bibliothek, die einen Behandlungsmechanismus für vorübergehende Fehler enthält. Die von ihm verwendete Wiederholungsrichtlinie ist in der Regel auf die Art und die Anforderungen des Zieldienstes zugeschnitten. Alternativ können REST-Schnittstellen für Dienste Informationen zurückgeben, auf deren Grundlage Sie bestimmen können, ob eine Wiederholung angebracht ist und wie lange bis zum nächsten Wiederholungsversuch gewartet werden sollte.

  • Verwenden Sie nach Möglichkeit den integrierten Wiederholungsmechanismus (sofern verfügbar) – es sei denn, Sie haben spezifische und klare Anforderungen, für die ein anderes Wiederholungsverhalten besser geeignet ist.

Ermitteln, ob der Vorgang für Wiederholungen geeignet ist

  • Wiederholen Sie Vorgänge nur bei vorübergehenden Fehlern (in der Regel ersichtlich anhand der Art des Fehlers) und wenn zumindest eine gewisse Wahrscheinlichkeit besteht, dass der Vorgang bei einem erneuten Versuch erfolgreich ist. Es bringt nichts, ungültige Vorgänge zu wiederholen – beispielsweise eine Datenbankaktualisierung für ein nicht vorhandenes Element oder eine Anforderung für Dienste oder Ressourcen, bei der ein schwerwiegender Fehler aufgetreten ist.

  • Allgemein gilt: Implementieren Sie Wiederholungen nur, wenn Sie sämtliche Auswirkungen dieser Vorgehensweise bestimmen können und die Bedingungen bekannt und überprüfbar sind. Überlassen Sie die Implementierung von Wiederholungen andernfalls dem aufrufenden Code. Denken Sie daran, dass sich die Fehler, die von Ressourcen und Diensten außerhalb Ihrer Kontrolle zurückgegeben werden, im Laufe der Zeit weiterentwickeln können und Sie dementsprechend womöglich Ihre Logik zur Erkennung vorübergehender Fehler überdenken müssen.

  • Wenn Sie Dienste oder Komponenten erstellen, empfiehlt sich ggf. die Implementierung von Fehlercodes und -meldungen, die Clients dabei helfen, zu bestimmen, ob nicht erfolgreiche Vorgänge wiederholen werden sollten. Geben Sie insbesondere an, ob der Client den Vorgang wiederholen soll (beispielsweise durch Rückgabe eines Werts vom Typ IsTransient), und schlagen Sie eine geeignete Verzögerung bis zum nächsten Wiederholungsversuch vor. Erwägen Sie bei der Erstellung eines Webdiensts, benutzerdefinierte Fehler zurückzugeben, die in Ihren Serviceverträgen definiert sind. Generische Clients können diese Fehler zwar möglicherweise nicht lesen, bei der Erstellung benutzerdefinierter Clients sind sie aber dennoch hilfreich.

Bestimmen einer geeigneten Wiederholungsanzahl und eines geeigneten Intervalls

  • Optimieren Sie die Anzahl von Wiederholungsversuchen und das Intervall unter Berücksichtigung des Anwendungsfalls. Wenn Sie einen Vorgang nicht oft genug wiederholen, kann die Anwendung den Vorgang nicht abschließen, und es tritt wahrscheinlich ein Fehler auf. Wenn Sie zu viele Wiederholungsversuche durchführen oder die Intervalle zwischen den einzelnen Versuchen zu kurz sind, beansprucht die Anwendung möglicherweise Ressourcen wie Threads, Verbindungen und Arbeitsspeicher für einen langen Zeitraum, was sich negativ auf die Integrität der Anwendung auswirkt.

  • Stimmen Sie die Werte für das Zeitintervall und die Anzahl von Wiederholungsversuchen auf die Art des Vorgangs ab. Wenn der Vorgang beispielsweise Teil einer Benutzerinteraktion ist, sollte das Intervall kurz sein, und es sollten nur wenige Wiederholungsversuche unternommen werden. So können Sie vermeiden, dass Benutzer auf eine Antwort warten müssen (wodurch Verbindungen offen gehalten werden und ggf. die Verfügbarkeit für andere Benutzer leidet). Wenn der Vorgang Teil eines zeitintensiven oder kritischen Workflows ist, bei dem ein Abbruch oder Neustart des Prozesses teuer oder zeitaufwendig wäre, empfiehlt es sich, zwischen den Versuchen länger zu warten und den Vorgang öfter zu wiederholen.

  • Die Bestimmung der geeigneten Intervalle zwischen Wiederholungen ist der schwierigste Teil beim Entwerfen einer erfolgreichen Strategie. Typische Strategien verwenden die folgenden Typen von Wiederholungsintervallen:

    • Exponentielles Backoff. Die Anwendung wartet vor dem ersten Wiederholungsversuch kurz und verlängert dann exponentiell den Abstand bis zur jeweils nächsten Wiederholung. So wird der Vorgang beispielsweise nach drei Sekunden, nach 12 Sekunden, nach 30 Sekunden usw. wiederholt.

    • Inkrementelle Intervalle. Die Anwendung wartet vor dem ersten Wiederholungsversuch kurz und verlängert dann schrittweise den Abstand bis zur jeweils nächsten Wiederholung. So wird der Vorgang beispielsweise nach drei Sekunden, nach sieben Sekunden, nach 13 Sekunden usw. wiederholt.

    • Regelmäßige Intervalle. Die Anwendung wartet zwischen jedem Versuch gleich lang. Beispielsweise wird der Vorgang alle drei Sekunden wiederholt.

    • Sofortiger Wiederholungsversuch. Manchmal ist ein vorübergehender Fehler kurz – gegebenenfalls ausgelöst durch ein Ereignis wie einen Netzwerkpaketkonflikt oder eine Auslastungsspitze in einer Hardwarekomponente. In diesem Fall bietet sich eine sofortige Wiederholung des Vorgangs an, da er möglicherweise erfolgreich ist, wenn der Fehler in der Zeit behoben wurde, die die Anwendung benötigt, um die nächste Anforderung zusammenzustellen und zu senden. Es sollte aber immer nur ein einzelner sofortiger Wiederholungsversuch unternommen werden. Ist der sofortige Wiederholungsversuch nicht erfolgreich, greifen Sie auf alternative Strategien wie exponentielles Backoff oder Fallbackaktionen zurück.

    • Zufällige Anordnung. Jede der hier angegebenen Strategien kann Randomisierung enthalten, um zu verhindern, dass mehrere Instanzen des Clients gleichzeitig weitere Wiederholungsversuche senden. Beispielsweise kann eine Instanz den Vorgang nach drei Sekunden, elf Sekunden, 28 Sekunden usw. wiederholen, während eine andere Instanz den Vorgang nach vier Sekunden, 12 Sekunden, 26 Sekunden usw. wiederholt. Randomisierung ist eine nützliche Technik, die mit anderen Strategien kombiniert werden kann.

  • Faustregel: Verwenden Sie für Hintergrundvorgänge eine Strategie mit exponentiellem Backoff und für interaktive Vorgänge eine Strategie mit sofortiger oder regelmäßiger Wiederholung. In beiden Fällen sollten Sie die Verzögerung und die Anzahl der Wiederholungsversuche so auswählen, dass die die maximale Latenz für alle Wiederholungsversuche innerhalb der erforderlichen End-to-End-Latenzzeit liegt.

  • Berücksichtigen Sie die Kombination aller Faktoren, die zum maximalen Timeout für einen wiederholten Vorgang beitragen. Zu diesen Faktoren zählen die Zeit, bis ein Verbindungsfehler zu einer Antwort führt (in der Regel durch einen Timeoutwert auf dem Client festgelegt), sowie die Verzögerung zwischen den Wiederholungsversuchen und die maximale Anzahl von Wiederholungen. Die Gesamtdauer kann zu einer langen Gesamtvorgangszeit führen. Das gilt insbesondere, wenn eine exponentielle Verzögerungsstrategie verwendet wird, bei der die Intervalle zwischen Wiederholungen nach jedem Fehler größer werden. Wenn ein Prozess eine bestimmte Vereinbarung zum Servicelevel (SLA) erfüllen muss, muss die Gesamtvorgangszeit, einschließlich aller Timeouts und Verzögerungen, innerhalb der im SLA definierten Grenzen liegen.

  • Implementieren Sie keine übermäßig aggressiven Wiederholungsstrategien. Damit sind Strategien mit zu kurzen Intervallen oder zu häufigen Wiederholungen gemeint. Sie können sich negativ auf die Zielressource oder auf den Zieldienst auswirken. Diese Strategien können dazu führen, dass sich Ressourcen oder Dienste nicht von ihrer Überlastung erholen und weiterhin Anforderungen blockieren oder ablehnen. Dies hat einen Teufelskreis zur Folge, bei dem mehr und mehr Anforderungen an die Ressource oder den Dienst gesendet werden. Dadurch wird die Wiederherstellung des Diensts bzw. der Ressource weiter erschwert.

  • Berücksichtigen Sie bei der Wahl der Wiederholungsintervalle das Timeout der Vorgänge, um zu vermeiden, dass sofort ein weiterer Versuch gestartet wird (beispielsweise, wenn der Timeoutzeitraum dem Wiederholungsintervall ähnelt). Überlegen Sie auch, ob der insgesamt mögliche Zeitraum (Timeout plus Wiederholungsintervalle) unter einer bestimmten Gesamtzeit bleiben muss. Vorgänge mit einem ungewöhnlich kurzen oder langen Timeout können die Wartezeit und die Anzahl von Wiederholungsversuchen für den Vorgang beeinflussen.

  • Ziehen Sie die Art der Ausnahme und alle darin enthaltenen Daten oder die Fehlercodes und Meldungen heran, die vom Dienst zurückgegeben werden, um die Anzahl von Wiederholungen und das Intervall zwischen ihnen zu optimieren. Zum Beispiel können einige Ausnahmen oder Fehlercodes (wie der HTTP-Code 503 „Dienst nicht verfügbar“ mit einem Retry-After-Header in der Antwort) angeben, wie lange der Fehler dauern kann oder dass der Dienst ausgefallen ist und nicht auf einen nachfolgenden Versuch reagieren wird.

Vermeiden von Antimustern

  • In den meisten Fällen sollten Sie Implementierungen vermeiden, die duplizierte Ebenen mit Wiederholungscode enthalten. Vermeiden Sie Entwürfe, die kaskadierende Wiederholungsmechanismen enthalten oder in jeder Phase eines Vorgangs, der eine Hierarchie von Anforderungen beinhaltet, eine Wiederholung implementieren, es sei denn, Sie haben spezielle Anforderungen, die dies erfordern. Verwenden Sie unter diesen besonderen Umständen Richtlinien, die eine übertriebene Anzahl an Wiederholungen und Verzögerungszeiträumen verhindern, und stellen Sie sicher, dass Sie die Folgen kennen. Ein Beispiel: Angenommen, eine Komponente sendet eine Anforderung an eine andere Komponente, die dann auf den Zieldienst zugreift. Wenn Sie für beide Aufrufe eine Wiederholung mit dem Wert 3 implementieren, gibt es insgesamt neun Wiederholungsversuche für den Dienst. Viele Dienste und Ressourcen implementieren einen integrierten Wiederholungsmechanismus. Untersuchen Sie, wie Sie diese deaktivieren oder ändern können, wenn Sie Wiederholungen auf einer höheren Ebene implementieren müssen.

  • Implementieren Sie niemals einen endlosen Wiederholungsmechanismus. Durch diese Vorgehensweise wird wahrscheinlich verhindert, dass sich die Ressource oder der Dienst von einer Überlastung erholt, und sie führt ggf. länger zu Drosselungen und Verbindungsverweigerungen. Verwenden Sie eine endliche Anzahl von Wiederholungen, oder implementieren Sie beispielsweise das Trennschalter-Muster, damit der Dienst wiederhergestellt werden kann.

  • Führen Sie nie öfter als einmal eine sofortige Wiederholung durch.

  • Vermeiden Sie die Verwendung eines regulären Wiederholungsintervalls, wenn Sie auf Dienste und Ressourcen in Azure zugreifen – insbesondere bei einer hohen Anzahl von Wiederholungsversuchen. Der beste Ansatz ist eine Strategie mit exponentiellem Backoff und Trennschalter-Funktion.

  • Vermeiden Sie, dass mehrere Instanzen des gleichen Clients oder mehrere Instanzen verschiedener Clients gleichzeitig Wiederholungen senden. Ist dieses Szenario wahrscheinlich, integrieren Sie Randomisierung in die Wiederholungsintervalle.

Testen Ihrer Wiederholungsstrategie und Ihrer Implementierung

  • Testen Sie Ihre Wiederholungsstrategie umfassend und unter möglichst vielfältigen Bedingungen – insbesondere, wenn die Anwendung und die von ihr verwendeten Zielressourcen oder -dienste stark ausgelastet sind. Um das Verhalten während der Tests zu überprüfen, können Sie folgende Aktionen ausführen:

    • Vorübergehende und dauerhafte Fehler in den Dienst einfügen. Senden Sie beispielsweise ungültige Anforderungen oder fügen Sie einen Code hinzu, der Testanforderungen und Antworten mit unterschiedlichen Fehlerarten erkennt. Ein Beispiel für die Verwendung von TestApi finden Sie unter Test Run - Fault Injection Testing with TestApi (Testlauf: Tests durch Fault Injection mit TestApi) sowie unter Introduction to TestApi – Part 5: Managed Code Fault Injection APIs (Einführung in TestApi – Teil 5: Fault Injection-APIs für verwalteten Code).

    • Simulieren Sie die Ressource oder den Dienst, die bzw. der eine Reihe von Fehlern zurückgibt, die auch vom tatsächlichen Dienst zurückgeben werden können. Decken Sie alle Arten von Fehlern ab, die von Ihrer Wiederholungsstrategie erkannt werden sollen.

    • Erzwingen Sie bei benutzerdefinierten Diensten, die Sie erstellen und bereitstellen, vorübergehende Fehler, indem Sie den Dienst vorübergehend deaktivieren oder überlasten. (Versuchen Sie nicht, gemeinsam genutzte Ressourcen oder Dienste innerhalb von Azure zu überlasten.)

    • Bei HTTP-basierte APIs empfiehlt sich ggf. die Verwendung einer Bibliothek in Ihren automatisierten Tests, um das Ergebnis der HTTP-Anforderungen durch Hinzufügen zusätzlicher Roundtrip-Zeiten oder durch Ändern der Antwort (z. B. den HTTP-Statuscode, Header, Text oder andere Faktoren) zu ändern. Dies ermöglicht deterministisches Testen einer Teilmenge der Fehlerbedingungen, und zwar sowohl für vorübergehende Fehler als auch für andere Fehlertypen.

    • Führen Sie Tests mit hoher Auslastung sowie gleichzeitige Tests durch, um sicherzustellen, dass der Wiederholungsmechanismus und die Wiederholungsstrategie unter diesen Bedingungen ordnungsgemäß funktionieren. Diese Tests tragen auch dazu bei, sicherzustellen, dass sich der Wiederholungsversuch nicht nachteilig auf den Betrieb des Clients auswirkt oder zu Kreuzkontaminationen zwischen Anforderungen führt.

Verwalten der Konfigurationen von Wiederholungsrichtlinien

  • Eine Wiederholungsrichtlinie ist eine Kombination aller Elemente Ihrer Wiederholungsstrategie. Sie definiert den Erkennungsmechanismus, der bestimmt, ob ein Fehler wahrscheinlich vorübergehend ist, und der die Art des zu verwendenden Intervalls (z. B. regelmäßig, exponentielles Backoff, Randomisierung), die tatsächlichen Intervallwerte und die Anzahl von Wiederholungen bestimmt.

  • Implementieren Sie Wiederholungen an vielen Stellen (auch bei ganz einfachen Anwendungen) sowie auf jeder Ebene von komplexeren Anwendungen. Es empfiehlt sich, einen zentralen Speicherort für alle Richtlinien zu verwenden, anstatt die Elemente der einzelnen Richtlinien an mehreren Orten hartzucodieren. Speichern Sie beispielsweise Werte wie die Intervalle und die Wiederholungsanzahl in Anwendungskonfigurationsdateien, lesen Sie sie zur Laufzeit, und erstellen Sie programmgesteuerte Wiederholungsrichtlinien. Dies erleichtert die Verwaltung der Einstellungen sowie Änderungen und Anpassungen der Werte, um auf geänderte Anforderungen und Szenarien zu reagieren. Entwerfen Sie das System aber so, dass die Werte gespeichert werden, anstatt jedes Mal eine Konfigurationsdatei neu zu lesen, und verwenden Sie geeignete Standardwerte, wenn die Werte aus der Konfiguration nicht abgerufen werden können.

  • Bei einer Azure Cloud Services-Anwendung empfiehlt es sich, die Werte, mit denen die Wiederholungsrichtlinien zur Laufzeit erstellt werden, in der Dienstkonfigurationsdatei zu speichern, damit sie ohne Neustart der Anwendung geändert werden können.

  • Nutzen Sie integrierte oder standardmäßige Wiederholungsstrategien in den von Ihnen verwendeten Client-APIs (vorausgesetzt, sie sind für Ihr Szenario geeignet). Diese Strategien sind in der Regel generisch. In einigen Szenarien ist womöglich nichts weiter erforderlich. In anderen Szenarien bieten sie dagegen möglicherweise nicht die gesamte Bandbreite von Optionen, die zur Erfüllung Ihrer Anforderungen benötigt werden. Zur Ermittlung der am besten geeigneten Werte müssen Sie Tests durchführen, um zu verstehen, wie sich die Einstellungen auf Ihre Anwendung auswirken.

Protokollieren und Nachverfolgen vorübergehender und dauerhafter Fehler

  • Schließen Sie als Teil Ihrer Wiederholungsstrategie die Ausnahmebehandlung sowie weitere Instrumentierung zur Protokollierung von Wiederholungsversuchen ein. Gelegentliche vorübergehende Fehler und Wiederholungsversuche sind zu erwarten und deuten nicht auf ein Problem hin. Regelmäßige und zunehmende Wiederholungen sind dagegen häufig ein Anzeichen für ein Problem, das zu einem Fehler führen kann oder die Anwendungsleistung und -verfügbarkeit beeinträchtigt.

  • Protokollieren Sie vorübergehende Fehler nicht als Fehler-, sondern als Warnungseinträge, damit Überwachungssysteme sie nicht als Anwendungsfehler erkennen und womöglich falsche Warnungen auslösen.

  • Speichern Sie ggf. einen Wert in Ihren Protokolleinträgen, der angibt, ob die Wiederholungen durch eine Drosselung des Diensts oder durch andere Fehlerarten (beispielsweise Verbindungsfehler) verursacht wurden, damit Sie sie bei der Datenanalyse unterscheiden können. Eine Zunahme der Anzahl der Drosselungsfehler ist häufig ein Hinweis auf einen Designfehler in der Anwendung oder auf die Notwendigkeit, zu einem Premium-Dienst zu wechseln, der dedizierte Hardware bietet.

  • Messen und protokollieren Sie ggf. die verstrichene Gesamtzeit für Vorgänge mit Wiederholungsmechanismus. Diese Metrik ist ein guter Indikator für die Gesamtauswirkung der vorübergehenden Fehler auf die Antwortzeiten der Benutzer, auf die Prozesswartezeit und auf die Effizienz der Anwendungsfälle der Anwendung. Protokollieren Sie auch die Anzahl von Wiederholungsversuchen, um die Faktoren zu verstehen, die in die Antwortzeit einfließen.

  • Implementieren Sie ggf. ein Telemetrie- und Überwachungssystem, das Warnungen auslöst, wenn es zu einer Zunahme bei der Anzahl und Rate von Fehlern, bei der durchschnittlichen Anzahl von Wiederholungen oder bei der für eine erfolgreiche Ausführung von Vorgängen benötigten Gesamtzeit kommt.

Verwalten von Vorgängen, die kontinuierlich nicht erfolgreich sind

  • Überlegen Sie sich eine Strategie für Vorgänge, bei denen keiner der Versuche erfolgreich ist. Situationen wie diese sind unvermeidlich.

    • Eine Wiederholungsstrategie definiert zwar, wie oft ein Vorgang höchstens wiederholt werden soll, sie verhindert jedoch nicht, dass die Anwendung den Vorgang mit der gleichen Anzahl von Wiederholungen erneut wiederholt. Tritt beispielsweise bei einem Dienst zur Bestellverarbeitung ein schwerwiegender Fehler auf, der diesen Dienst dauerhaft außer Betrieb setzt, erkennt die Wiederholungsstrategie möglicherweise ein Verbindungstimeout und betrachtet es als vorübergehenden Fehler. Der Code führt für den Vorgang eine bestimmte Anzahl von Wiederholungsversuchen durch und gibt schließlich auf. Wenn jedoch ein anderer Kunde eine Bestellung aufgibt, wird der Vorgang erneut versucht, obwohl er nie erfolgreich sein wird.

    • Implementieren Sie das Trennschalter-Muster, um die kontinuierliche Wiederholung von Vorgängen zu vermeiden, die nie erfolgreich sind. Bei diesem Muster gilt: Wenn die Anzahl von Fehlern in einem angegebenen Zeitfenster einen Schwellenwert übersteigt, werden Anforderungen umgehend als Fehler an den Aufrufer zurückgegeben, und es wird nicht versucht, auf die fehlerhafte Ressource oder auf den fehlerhaften Dienst zuzugreifen.

    • Die Anwendung kann in regelmäßigen Abständen, auf zeitweiliger Basis und mit langen Intervallen zwischen den Anforderungen den Dienst testen, um zu erkennen, wann er wieder verfügbar ist. Ein geeignetes Intervall hängt von Faktoren wie der Wichtigkeit des Vorgangs und der Art des Diensts ab. Es kann zwischen einigen Minuten und mehreren Stunden liegen. Ist der Test erfolgreich, kann die Anwendung normal fortgesetzt werden und Anforderungen an den wiederhergestellten Dienst übergeben.

    • In der Zwischenzeit können Sie ggf. auf eine andere Instanz des Diensts (z. B. in einem anderen Rechenzentrum oder in einer anderen Anwendung) zurückgreifen, einen ähnlichen Dienst mit kompatiblen (ggf. einfacheren) Funktionen nutzen oder alternative Vorgänge ausführen und darauf hoffen, dass der Dienst schnell wieder verfügbar ist. So kann es beispielsweise angebracht sein, die Anforderungen für den Dienst in einer Warteschlange oder in einem Datenspeicher zu speichern und sie später zu wiederholen. Alternativ können Sie möglicherweise den Benutzer zu einer anderen Instanz umleiten, die Leistung der Anwendung bei immer noch akzeptabler Funktion herabsetzen oder einfach eine Nachricht an den Benutzer zurückgeben, aus der hervorgeht, dass die Anwendung derzeit nicht verfügbar ist.

Weitere Überlegungen

  • Wenn Sie die Werte für die Anzahl von Wiederholungen und die Wiederholungsintervalle für eine Richtlinie festlegen, berücksichtigen Sie, ob der Dienst oder die Ressource Teil eines zeitintensiven oder aus mehreren Schritten bestehenden Vorgangs ist. Es kann schwierig oder teuer sein, alle bereits erfolgreich abgeschlossenen Vorgangsschritte zu kompensieren, wenn ein einzelner Schritt fehlschlägt. In diesem Fall sind ggf. ein sehr langes Intervall und eine große Anzahl von Wiederholungen akzeptabel, solange diese Strategie keine anderen Vorgänge blockiert, da knappe Ressourcen beansprucht oder gesperrt werden.

  • Überlegen Sie, ob eine Wiederholung des gleichen Vorgangs möglicherweise zu inkonsistenten Daten führt. Wenn einige Teile eines aus mehreren Schritten bestehenden Prozesses wiederholt werden und die Vorgänge nicht idempotent sind, kann dies zu Inkonsistenzen führen. Beispielsweise erzeugt ein Vorgang, der bei Wiederholung einen Wert inkrementiert, ein ungültiges Ergebnis. Die Wiederholung eines Vorgangs, der eine Nachricht an eine Warteschlange sendet, kann eine Inkonsistenz im Nachrichtenconsumer verursachen, wenn dieser doppelte Nachrichten nicht erkennen kann. Gestalten Sie jeden Schritt als idempotenten Vorgang, um derartige Szenarien zu vermeiden. Weitere Informationen finden Sie unter Idempotency Patterns (Idempotenzmuster).

  • Berücksichtigen Sie den Bereich der Vorgänge, die wiederholt werden. Beispielsweise ist es möglicherweise einfacher, einen Wiederholungscode auf einer Ebene zu implementieren, die mehrere Vorgänge umfasst, und sie alle zu wiederholen, wenn einer der Vorgänge nicht erfolgreich war. Allerdings kann dies zu Idempotenzproblemen oder zu unnötigen Rollbackvorgängen führen.

  • Berücksichtigen Sie bei der Verwendung eines Wiederholungsbereichs, der mehrere Vorgänge umfasst, die gesamte Wartezeit aller Vorgänge, wenn Sie die Wiederholungsintervalle bestimmen, wenn Sie die verstrichene Zeit des Vorgangs überwachen und bevor Sie Warnungen für Fehler auslösen.

  • Beachten Sie, wie Ihre Wiederholungsstrategie Nachbarn und andere Mandanten in einer gemeinsam genutzten Anwendung sowie bei Verwendung von gemeinsam genutzten Ressourcen und Diensten beeinflussen kann. Aggressive Wiederholungsrichtlinien können für diese anderen Benutzer und für Anwendungen, die Ressourcen und Dienste teilen, vermehrt zu vorübergehenden Fehlern führen. Ebenso kann Ihre Anwendung durch Wiederholungsrichtlinien beeinträchtigt werden, die von anderen Benutzern der Ressourcen und Dienste implementiert wurden. Für unternehmenskritische Anwendungen können Sie Premium-Dienste verwenden, die nicht gemeinsam genutzt werden. Dadurch erhalten Sie mehr Kontrolle über die Auslastung und die sich daraus ergebende Drosselung dieser Ressourcen und Dienste, was hilfreich sein kann, um die zusätzlichen Kosten zu rechtfertigen.