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.
Antworten:
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.
quelle
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/
quelle