charlyalto - Fotolia

Typische Fehler in ereignisgesteuerten Architekturen beheben

Das Hinzufügen von Ereignissen zu einer Architektur kann viele Probleme mit sich bringen. Häufige Fehler in ereignisgesteuerten Architekturen und wie man sie behebt.

Fast alle schlecht geschriebenen Softwarespezifikationen erwähnen in den Programmieranforderungen, dass Fehler angemessen behandelt werden. Leider wird mit dieser schwammigen Aussage nicht gesagt, wie Entwickler mit Fehlern umgehen – wenn sie potenzielle Fehler überhaupt auflisten.

Dieses Problem verschärft sich noch, wenn ereignisgesteuerte Systeme ins Spiel kommen, die nach Belieben Nachrichten in eine Warteschlange stellen können, ohne die Verantwortung dafür zu übernehmen, was als nächstes geschieht. Wenn man bedenkt, wie viel schwieriger es dadurch wird, Fehler nicht nur zu verfolgen, sondern auch kaskadierende Ausfälle zu verhindern, müssen alle Spezifikationen für ereignisgesteuerte Systeme die spezifischen Probleme im Zusammenhang mit ereignisgesteuerten Methoden aufzeigen und Abhilfemaßnahmen für jedes Problem vorschreiben.

In diesem Artikel werfen wir einen detaillierten Blick auf einige der häufigsten Fehler in ereignisgesteuerten Architekturen (Event-driven Architecture), mit denen Entwicklungsteams konfrontiert sind, sowie auf Techniken, die sich im Laufe der Jahre als Gegenmaßnahmen etabliert haben.

Arten von Fehler

Ein ereignisgesteuertes System besteht aus mindestens drei Teilen: den Komponenten, die Anfragen senden, Komponenten, die sie empfangen und verarbeiten (und möglicherweise ein Ergebnis zurückliefern), und einem Messaging Broker, der die Transaktion erleichtert. Jedes dieser Systeme kann ausfallen oder den Ausfall eines anderen Systems verursachen, und die Fehlerbehandlung in ereignisgesteuerten Architekturen kann somit eine große Hürde darstellen.

Hier sind einige der häufigsten Situationen, denen Entwickler begegnen:

Fehlgeschlagenes Rückgabeergebnis

Ein fehlgeschlagenes Rückgabeergebnis tritt auf, wenn ein System eine Anfrage erhält, aber nicht das vom Anfragenden erwartete Ergebnis zurückgeben kann. Dies ist zum Beispiel der Fall, wenn eine Kreditkarte während einer Transaktion abgelehnt wird oder ein Lager einen angeforderten Artikel nicht vorrätig hat.

Das empfangende System verarbeitet die Anfrage, gibt aber ein Fehlerergebnis zurück. In ereignisgesteuerten Systemen können die Ereignisse, die Anforderungen übertragen, einfach eine Benachrichtigung in eine Nachrichtenwarteschlange stellen und weitergehen. Das bedeutet, dass ein separater Prozess für die Erkennung des Fehlers und die entsprechende Behandlung zuständig ist.

Ausfall des Remote-Service

In diesem Fall ist das System, das ein Anfragesteller erreichen möchte, nicht in Betrieb. So kann beispielsweise ein Auftragseingabesystem einen Auftrag und die Auftragskennung erhalten, und ein Event Handler kann die Nachricht in eine Warteschlange für das Kreditkartensystem stellen, aber das Kreditkartensystem wird die Anfrage nie erhalten. In einem Event-Streaming-System bleibt die Nachricht in der Warteschlange stecken, während sie darauf wartet, dass der Empfänger sie abholt, was zu einem ständig wachsenden Stapel von Anfragen führt, die den Warteschlangenmechanismus oder die anfordernden Dienste überlasten.

Event Routing schlägt fehl

Wenn ein Ereignis nicht mit dem Prozess übereinstimmt, den es auslösen soll, wird es möglicherweise nie vom richtigen System abgeholt. Ein System, das zum Beispiel Nachrichten über Kundenbestellungen empfangen muss, wird nicht funktionieren, wenn es nicht den richtigen Ereignistyp abonniert hat. Dies führt zu der gleichen Situation wie ein ausgefallenes System, da die Anfrage nie ein Ergebnis liefern wird.

Ausfall des Ereignisbehandlungssystems

Dies tritt auf, wenn ein Mechanismus zur Einreihung von Nachrichten in eine Warteschlange seine Aufgabe nicht erfüllt, was bei einer schlechten Konfiguration der Nachrichtenverarbeitung der Fall sein kann. Es ist auch möglich, ein Messaging-System so zu konzipieren, dass es hochverfügbar ist, und dabei die eine oder andere Komponente zu vergessen, die einen kritischen Prozess unterstützt. Das ursprünglich anfragende System kann einwandfrei funktionieren, ebenso wie der vorgesehene Empfänger, aber die Nachricht, von der angenommen wurde, dass sie gesendet wird, wird nie weitergeleitet.

Wege zum Umgang mit Fehlern in ereignisgesteuerten Architekturen

Trotz aller Probleme, die diese Art von Systemen plagen, gibt es einige verlässliche Methoden und Muster für die Ereignisbehandlung in ereignisgesteuerten Architekturen. Hier sind einige davon, die man sich merken sollte:

Dead-Letter-Warteschlangen

Eine Dead-Letter-Warteschlange ist eine Sammlung von Nachrichten, die, aus welchem Grund auch immer, nie vom vorgesehenen Empfänger abgeholt und verarbeitet wurden. In regelmäßigen Abständen kann eine implementierte Bereinigungsroutine die Dead-Letter-Warteschlange durchkämmen, das Problem feststellen und diese verlorenen Nachrichten entsprechend behandeln.

Diese Routine kann auch so programmiert werden, dass sie bei Bedarf alte Aufträge wieder aufnimmt und neu zustellt. Zumindest kann sie die anfragenden Systeme darüber informieren, dass der vorgesehene Empfänger nicht erreichbar ist.

Entwurfsmuster (Saga Pattern)

Das Entwurfsmuster verwendet sowohl einen Messaging Bus als auch einen Controller-Mechanismus, der Ereignisse von diesem Bus empfängt und sie in prozessbasierte Nachrichten umwandelt. Dieser Controller kann so etwas wie ein endlicher Zustandsautomat sein, der eine sequenzielle Logik simuliert – irgendetwas, das die Nachricht entgegennimmt, feststellt, woher sie kam, ihren Status analysiert und dann den nächsten Befehl verarbeitet. Dies kann zum Beispiel mit einer Switch-Anweisung oder einer Reihe von verschachtelten IF-Befehlen bewerkstelligt werden.

Auf diese Weise wird ein einigermaßen ausgeklügeltes Rollback-System für Fehler in einer ereignisgesteuerten Architektur implementiert, da der Dienst den Bus über einen Fehler informieren kann, was den Controller veranlasst, Rollback-Anweisungen an jeden Dienst entlang der Ausführungskette zu senden. Bedenken Sie jedoch, dass dieser Controller-Mechanismus viel mehr Code hinzufügt, was ein einfaches Anwendungssystem schnell in ein komplexes Netz von Abhängigkeiten und potenziellen Fehlern verwandeln kann.

Protokolle und Warnungen

Das System, das den Fehler sendet oder empfängt, möchte möglicherweise Warnungen in ein Protokoll schreiben, dass etwas schiefgelaufen ist. Diese Warnungen können sich in Form von Webseiten, E-Mails, Sofortnachrichten oder Telefonanrufen äußern, auf die der Benutzer reagiert.

Diese Meldungen sollten so viel Kontext haben, dass ein Administrator das Problem beheben kann. Eine Möglichkeit, mit Warnmeldungen konsistent zu bleiben, besteht darin, dass die Entwicklungsteams ihren eigenen Support bereitstellen, indem sie einen Rotationsplan einführen, der bestimmten Entwicklern Support-Rollen zuweist, die die Verantwortung für Fehlerbehebungen, Korrekturen und, falls erforderlich, Eskalationen übernehmen.

Erfahren Sie mehr über Softwareentwicklung