Wie gestalten Sie Ihre Software, die mehrere Microservices aktualisiert, wenn einer von ihnen ausfällt?

12

Gibt es ein Entwurfsmuster oder eine Entwurfspraxis, mit der ich bei Diensten helfen kann, die entweder ausfallen oder ausfallen, während andere stabil sind?

Was ist, wenn ich drei Microservices habe und zwei davon gut sind und einer mitten in einem POST stirbt? Zwei erhalten den POST und einer nicht. Ich glaube nicht, dass ich Transaktionen durchführen kann, weil ich meine Anfragen an einen Dienst versende.

Wie entwerfe ich das? Ich möchte keine verwaisten Daten in verschiedenen Datenbanken.

Johnny
quelle
6
Es ist kein einfaches Problem zu lösen. Ich habe gesehen, dass es als Warteschlange für die Dienste implementiert ist (eventuelle Konsistenz), da Sie höchstwahrscheinlich nicht die Kontrolle über die Dienste haben und das Auferlegen von Transaktionsmanagern oder Transaktionsfunktionen bestenfalls ein Mist ist und wahrscheinlich keine gute Idee in einer SOA-Umgebung. Ich habe dies meistens bei mobilen Pushs gesehen, bei denen Sie möglicherweise eine Verbindung zu Ihrem Ziel haben oder nicht.
Mike
Säure über Microservices ist eine schwierige Nuss. Eine andere Option könnte eine Art Bus sein, der Redis Publish / Subscribe oder ein Warteschlangendesign verwendet und einmal vom eingehenden Kanal aus postet. Dann werden Ihre Abonnementdienste oder Service-Proxys zu den Zielen weitergeleitet und melden den Erfolg Fehler. Sie müssen auf Fehler überwachen und auch einen Flow dafür haben. Sie können auch Fehler haben, bei denen die Transaktion nicht für einen Dienst gültig ist, sondern für zwei andere, sondern nur einen weiteren Fehlerfluss, den Sie beheben müssen.
Tim Cederquist
Würde man nicht so etwas wie "Warteschlangenmanager" verwenden, was Redis wohl zu einem Engpass führen würde? Oder zumindest auch ein hohes Potenzial? Ich kenne auch keinen anderen Weg als den, den Sie beschrieben haben.
Johnny
Abhängig vom Datenflussvolumen habe ich einen Warteschlangenmanager implementiert, der Übertragungen wiederholt, bis ein Erfolg gemeldet wird, oder eine fehlgeschlagene Benachrichtigung sendet und eine SMS-Benachrichtigung über den Ausfall sendet. Ich denke, es würde auch ein bisschen vom erwarteten Ausfallfenster abhängen (wie lange).
htm11h
Ist das, wofür so etwas wie Rabbitmq ist?
Johnny

Antworten:

9

Einige Optionen.

Verwenden Sie einen dauerhaften Kommunikationskanal

Legen Sie anstelle von HTTP Nachrichten in einer Warteschlange ab, die hochverfügbar und dauerhaft ist. ZB Kafka. Solange der Zielserver irgendwann verfügbar ist, erhält er die Nachricht.

Sie haben den Kompromiss, jetzt ein komplexes Subsystem (die Warteschlange) bereitzustellen und zu verwalten. Stellen Sie also sicher, dass Sie analysieren, ob sich dies lohnt.

Zurücksetzen und erneut versuchen

Lassen Sie den Anrufer die fehlgeschlagene Anforderung (möglicherweise auf der Festplatte beibehalten) beibehalten und es regelmäßig wiederholen. In diesem Fall ist es wichtig, zwischen Ihrer Anfrage, die einen Absturz verursacht, und dem gerade ausgefallenen Dienst zu unterscheiden. Ersteres ist wahrscheinlich auf einen Fehler zurückzuführen und sollte protokolliert werden ... Wiederholungsversuche werden wahrscheinlich keinen Unterschied machen, bis eine Korrektur vorgenommen wurde.

Erkennen und kompensieren

Eine regelmäßige Aufgabe überprüft die Konsistenzbedingungen zwischen Microservices. ZB Fehlerprotokolle bis hin zu direkten API-Abfragen nach Bedarf. Wenn ein Problem festgestellt wird (z. B. wenn eine Bestellung vorliegt, der Versand jedoch nie eine Packliste erhalten hat), führen Sie Ausgleichsschritte aus. Diese Schritte können darin bestehen, ein Support-Ticket für eine manuelle Korrektur zu erstellen oder jemandem eine E-Mail zu senden oder was auch immer.

Erwägen Sie Entwurfsalternativen

In einem solchen Fall ist wahrscheinlich ein API-Gateway erforderlich, um Anrufe an betroffene Microservices zu verwalten. Auf diese Weise steuern Sie, mit welchen Taktiken dieses Problem behoben werden kann. Sie möchten Clients wahrscheinlich nicht mit diesen Implementierungsdetails belasten. Siehe Leistungsschaltermuster .

Da Microservices unabhängig sind, gibt es immer einen Fehlerfall, der zu Inkonsistenzen führen kann. Sie müssen bereit sein, manuelle Korrekturen vorzunehmen, wenn diese auftreten.

Wenn Sie eine starke Konsistenz benötigen, sind Microservices nicht geeignet. Wenn Sie weiterhin Skalierbarkeit benötigen, sollten Sie sich mit Sharding befassen, bei dem verwandte Daten aus Konsistenzgründen auf demselben Shard gespeichert werden können. Sie können E / A weiterhin skalieren, indem Sie Shards hinzufügen.

Wenn Sie eine starke Konsistenz benötigen und keine Skalierbarkeitsprobleme haben, verwenden Sie einfach monolithische Dienste. Verwenden Sie Bibliotheken als Grenzen in Ihrer Anwendung, um Bedenken zu trennen.

Kasey Speakman
quelle
Ist das, wofür RabbitMQ ist?
Johnny
Ist RabbitMQ die Antwort auf Ihre Frage? Nein. Es könnte Teil einer Lösung sein, die Ihren Anforderungen entspricht, aber es wird Ihr Problem nicht alleine lösen.
Kasey Speakman
Nur eine Notiz. Ich denke, RabbitMQ hält die Nachrichten nicht aufrecht. Es wird verbraucht und aus der Warteschlange entfernt, also NEIN. Wenn Sie Ausdauer benötigen und es erneut versuchen, hilft RabbitMQ nicht weiter.
Laiv
2

Ich denke, was Sie beschreiben, ist das Konsensproblem: Sie möchten sich nicht festlegen, es sei denn, jeder Teilnehmer an der verteilten Transaktion gibt an, dass der Vorgang erfolgreich war. Die einfache Lösung hierfür ist das Two Phase Commit. Im Wesentlichen wird die Transaktion in jedem System so lange inszeniert, bis jedes System meldet, dass die Bereitstellung erfolgreich war (Phase 1). Wenn jeder Teilnehmer an der Transaktion Erfolg hat, wird jeder aufgefordert, sich zu verpflichten. Wenn einer von ihnen stattdessen einen Fehler zurückgibt, wird ein Rollback ausgegeben (Phase 2). Dies hat eine Falte, die Sie zu der komplexeren Drei-Phasen-Commit-Lösung führt. Eine viel bessere Beschreibung von jedem können Sie hier lesen:

http://the-paper-trail.org/blog/consensus-protocols-two-phase-commit/

http://the-paper-trail.org/blog/consensus-protocols-three-phase-commit/

iarejenius
quelle