2016-04-14 12 views
3

Die Firma, für die ich arbeite, untersucht den Wechsel von unserer derzeitigen monolithischen API zu Microservices. Unsere aktuelle API ist stark vom Frühling abhängig und wir verwenden SQL Server für die meisten Persistenz. Unsere Microservice-Untersuchung orientiert sich an Spring-Cloud, Spring-Cloud-Stream, Kafka und Polyglot Persistence (isolierte Datenbank pro Microservice).microservice messaging db-assigned identifiers

Ich habe eine Frage darüber, wie Messaging über Kafka typischerweise in einer Microservice-Architektur erfolgt. Wir planen eine Koordinierungsschicht zwischen den Microservices und unseren Client-Anwendungen, die Aktivitäten über verschiedene Microservices hinweg koordinieren und Clients von Änderungen an Microservice-APIs isolieren. Die meisten Dinge, die wir über die Verwendung von spring-cloud-stream und kafka gelesen haben, weisen darauf hin, dass wir Ströme auf der Koordinationsebene (Quelle) für Ressourcenwechseloperationen (Einfügungen, Aktualisierungen, Löschungen) verwenden sollten, wobei der Microservice ein Verbraucher der Mitteilungen.

Wo habe ich Probleme mit diesem ist Einsätze. Wir verwenden stark Datenbank-zugewiesene Bezeichner (Identitätsspalten/Autoinkrementspalten/-sequenzen/Ersatzschlüssel) und sie werden normalerweise als Teil einer Postanforderung zugewiesen und an den Aufrufer zurückgegeben. Die Koordinationsschicht kann unter Verwendung verschiedener Microservices mehrere Dinge speichern und benötigt oft den zugewiesenen Identifizierer von einer Einfügung, bevor sie mit der nächsten Operation fortfahren kann. Die Verwendung von Nachrichtenaustausch zwischen der Koordinationsebene und den Microservices für Einfügungen bewirkt, dass die Koordinationsebene keine Antwort von der Einfügeoperation erhalten kann, so dass sie nicht die zugewiesene Kennung erhalten kann, die sie benötigt. Außerdem benötigen andere Verbraucher im Strom (d. H. Verbraucher, die die Daten in einem Data Warehouse veröffentlichen) die Nachricht, dass sie den zugewiesenen Bezeichner enthalten müssen.

Wie gehen Menschen mit diesem Problem um? Sind Datenbank-zugewiesene Identifikatoren ein Anti-Pattern in Microservices? Sollten wir separate Microservice-Endpunkte verfügbar machen, die datenbankzugewiesene Identifikatoren zurückgeben, so dass die Koordinationsebene einen synchronen Aufruf durchführen kann, um vor dem Aufruf des asynchronen Einfügens einen Bezeichner zu erhalten? Wir könnten UUIDs verwenden, aber unsere DBAs hassen diese als Primärschlüssel, und sie könnten nicht als Bestellnummer oder andere benutzergenerierte generierte IDs verwendet werden.

Antwort

1

Wenn Sie den Bezeichner programmgesteuert früher beim Empfangen aus der Nachrichtenquelle erstellen können, können Sie den Bezeichner als Teil des Nachrichtenheaders einbetten und anschließend die Nachrichtenkopfinformationen während der Datenbankeinfügungen und bei allen anderen Konsumenten verwenden.

Aber dieser Ansatz erfordert eine separate Überprüfung durch die anderen Verbraucher gegen die Datenbank, nur die committed-Transaktionen zu verarbeiten (wenn Sie besorgt sind, nur die Einsätze zu verarbeiten).

0

In unserem Unternehmen haben wir einen dedizierten Service aufgebaut, der für eine einzigartige IDs-Generation verantwortlich ist. Und alle anderen Dienste graben von dort die benötigten Informationen.

Diese generierten IDs konnten nicht als Bestellnummer verwendet werden, aber ich denke, sie sollte sowieso nicht für diesen Job verwendet werden. Wenn Sie nach Erstellungsdatum sortieren müssen, ist es besser, ein created_date-Feld zu haben.

Eine weitere Sache, die verwendet wird, um meine Meinung mit diesem Ansatz zu ärgern, ist, dass die primäre Ressource nach der anderen Ressource bestehen bleiben könnte, die sie durch die ID erneut betrifft. Beispielsweise werden ein Benutzer zum Einfügen und das Einfügen von Benutzeradressanforderungsnutzinformationen asynchron gesendet. Die Benutzerdaten für das Einfügen enthalten eine generierte eindeutige ID, und die Benutzeradressnutzlast enthält diese ID als fremde Referenz zurück an den Benutzer. Die Einfügebenutzeradresse wird möglicherweise vor der Benutzeranforderung verarbeitet, ist aber völlig in Ordnung. Ich denke, es heißt eventuelle Konsistenz.