it-swarm.com.de

So strukturieren Sie Microservices in Ihrem Repository

Ich bin einem Projekt zugeordnet, in dem wir ungefähr 20 Mikrodienste haben. Jeder von ihnen befindet sich in einem separaten Repository ohne Verweise auf einen anderen, abgesehen von einem Nuget-Paket, in dem wir generischen Code wie mathematische Funktionen verwalten. Jeder Dienst verweist die anderen nach Endpunkten.

Der Vorteil davon ist:

  • Jeder Dienst ist sehr unabhängig. (In Wirklichkeit steht dieser Punkt zur Diskussion, da eine Änderung der API eines Dienstes wahrscheinlich mehrere andere betrifft.)

  • Best Practice - laut Leuten, mit denen ich gesprochen habe

Der Nachteil sind:

  • Keine Wiederverwendung von Code.

  • Einige DTO-Objekte werden mehrfach definiert (möglicherweise bis zu 10)

  • Jede ServiceCommunication-Hilfsklasse, die die Endpunkte eines Dienstes zur Vereinfachung der Verwendung umschließt, wird mehrmals dupliziert, einmal für jedes Repo.

  • API-Änderungen sind schwer nachzuverfolgen. Oft sehen wir den Fehler in Test/Produktion

Ich denke, das Folgende ist ein besserer Weg, um das Projekt zu strukturieren: Ein Repo. Jeder Mikrodienst stellt eine Server.Communication-Hilfsklasse bereit, die die Endpoinds umschließt, und eine Auswahl von Server.Dto-Typen, die die Server.Communication-Klasse von ihren API-Aufrufen zurückgibt. Wenn ein anderer Dienst es verwenden möchte, wird dies eingeschlossen.

Ich hoffe, ich habe das Problem gut genug erklärt. Ist dies eine bessere Lösung, um einige meiner Probleme anzugehen, oder werde ich am Ende unvorhergesehene Probleme verursachen?

10
user1038502

Keine Wiederverwendung von Code wird normalerweise als Verkaufsargument für Microservices verstanden!

  • die Microservices können unabhängig voneinander entwickelt und bereitgestellt werden
  • unterschiedliche Microservices können unterschiedliche Technologien verwenden, insbesondere unterschiedliche Programmiersprachen

Wenn dies nicht als Vorteil erscheint - insbesondere wenn alle Microservices von einem Team unter Verwendung eines Technologie-Stacks entwickelt und zusammen bereitgestellt werden -, benötigen Sie möglicherweise keine Microservices, sondern eine Reihe von Bibliotheken. Und Sie können alle Bibliotheken/Dienste in einem Monorepo verwalten.

Wenn wir Skalierbarkeitsargumente für einen Moment ignorieren, Bibliotheken sind Microservices weitaus vorzuziehen. Eine Microservice-API ist effektiv dynamisch typisiert, was eine Fehlerquelle sein kann - genau wie Sie es erlebt haben. Im Gegensatz dazu werden Bibliotheks-APIs normalerweise statisch typisiert, wodurch eine ganze Klasse von Fehlern durch die Typprüfung zur Kompilierungszeit verhindert werden kann. Auch Intellisense ist nett. Bibliotheken, die innerhalb desselben Prozesses ausgeführt werden, sind in der Regel viel einfacher zu verwenden als verteilte Systeme, die ihre eigenen Herausforderungen haben, insbesondere in Bezug auf Netzwerkfehler, Konsistenz und verteilte Transaktionen.

Die Verwendung einer Microservice-Architektur bedeutet, dass Sie diese Nachteile akzeptieren, da Sie mit Microservices noch größere Probleme wie organisatorische Skalierbarkeit (verschiedene Teams entwickeln lassen) lösen können und stellen ihre Dienste unabhängig voneinander bereit) und technische Skalierbarkeit (verschiedene Teile des Systems separat skalieren).

Es gibt möglicher Mittelweg zwischen Bibliotheken und Microservices, die Ihr Leben ein bisschen einfacher machen können.

Beispielsweise kann ein Mikrodienst ein Client-Bibliothek zum Herstellen einer Verbindung mit diesem Mikrodienst bereitstellen. Diese Bibliothek verarbeitet Verbindungsdetails und bietet eine Reihe von Datenübertragungsobjekten. Bei korrektem Design können ältere Bibliotheksversionen weiterhin mit neueren Versionen des Microservice interagieren, sodass sie etwas unabhängig voneinander aktualisiert werden können. Dies erfordert jedoch, dass alle Benutzer dieses Mikrodienstes dieselbe Programmiersprache verwenden und dass diese Benutzer ihre Clientbibliothek innerhalb eines angemessenen Zeitrahmens aktualisieren können. Ein solcher Ansatz kann für ein Team nützlich sein, das mit der Verwendung von Microservices begonnen hat, ohne die Auswirkungen zu verstehen, ist jedoch normalerweise nicht praktikabel, wenn Sie Microservices aufgrund ihrer organisatorischen Skalierbarkeitsvorteile verwenden.

Eine mildere Version davon ist die Verwendung einer Dienstbeschreibungssprache, die eine sprachunabhängige API-Definition bereitstellt. Clients können dann Tools zur Codegenerierung verwenden, um DTOs und Verbindungsbibliotheken in ihrer Programmiersprache zu generieren. Dadurch werden die Dienste erfolgreich von anderen entkoppelt, während die Möglichkeit von API-Fehlanpassungsfehlern vermieden wird. Wenn Sie in dieser Dienstbeschreibungssprache arbeiten müssen, wird es auch schwieriger, die Abwärtskompatibilität versehentlich zu unterbrechen. Sie müssen jedoch zusätzliche Tools erlernen, und die Verwendung des generierten Codes kann schwierig sein. Dies ist normalerweise der richtige Weg in Unternehmensumgebungen.

Möglicherweise können Sie auch erweiterte Testmethoden anwenden, um eine API-Nichtübereinstimmung auszuschließen, z. Integrationstests aufzeichnen/wiedergeben: Zuerst führen Sie die Testfälle eines Clients für einen echten Microservice aus und zeichnen die Anforderungen und Antworten auf. Das Artefakt dieser Aufzeichnung wird vom Client und vom Microservice gemeinsam genutzt. Die Aufzeichnungen können dann in den Client-Tests verwendet werden, um einen nachgebildeten Mikroservice bereitzustellen, der die vordefinierten Antworten wiedergibt. Die Aufzeichnungen werden auch vom Mikrodienst verwendet, um zu überprüfen, ob der Dienst weiterhin dieselben Antworten liefert. Leider kann es schwierig sein, diese Aufzeichnungen zu aktualisieren, um Änderungen Rechnung zu tragen. Die Aufzeichnungen können auch sehr zerbrechlich sein, z. wenn irrelevante Metadaten wie genaue Daten nicht bereinigt werden. Ich arbeite derzeit an der Umstellung einer ähnlichen Testsuite, aber die Fragilität, von genau aufgezeichneten Antworten abhängig zu sein, macht dies unglaublich schwierig.

12
amon