Microservices und gemeinsam genutzte Bibliotheken

9

Wir entwerfen ein System, das auf unabhängigen Mikrodiensten basiert (verbunden über einen RabbitMq-Bus). Der Code wird (zumindest für die ersten Komponenten) in Python geschrieben (sowohl in Python2 als auch in Python3). Wir haben bereits eine Monolith-Anwendung, die einen Teil der Geschäftslogik implementiert, die wir als Microservices umgestalten und erweitern möchten. Eine Frage, die mich beunruhigt, ist:

Was ist der beste Weg, um Code zwischen den verschiedenen Microservices zu teilen? Wir haben gemeinsame Hilfsfunktionen (Datenverarbeitung, Protokollierung, Analyse der Konfiguration usw.), die von mehreren Mikrodiensten verwendet werden müssen.

Die Microservices selbst werden als separate Projekte (Git-Repositories) entwickelt. Die gemeinsamen Bibliotheken können auch als eigenständiges Projekt entwickelt werden. Wie teile ich diese Bibliotheken zwischen den Microservices?

Ich sehe mehrere Ansätze:

  • Kopieren Sie die Version der Bibliothek, die für jeden Microservice benötigt wird, und aktualisieren Sie sie nach Bedarf
  • Geben Sie die allgemeinen Bibliotheken für ein internes PyPi frei und listen Sie diese Bibliotheken als Abhängigkeiten in den Anforderungen des Microservices auf
  • Fügen Sie das Bibliotheks-Repository als Git-Submodul hinzu

Ich würde gerne etwas mehr über vorgeschlagene Ansätze, Best Practices und frühere Erfahrungen lesen, bevor ich mich für ein Vorgehen entscheide. Haben Sie einen Vorschlag oder Link?

verdammt schnell
quelle
Ich bin selbst nicht gut genug mit Microservices vertraut (mein Unternehmen hat kürzlich damit begonnen, etwas Ähnliches zu tun), um zu antworten, aber hier ist ein Link zu einer Präsentation darüber, warum das, was Sie beschreiben, eine rote Fahne ist und zu einem "verteilten Monolithen" führen kann. . Für Microservices sollten keine gemeinsam genutzten Bibliotheken erforderlich sein. Sie sollten eigentlich nur zwischen einer gut definierten API wie Swagger (jetzt Open API genannt ) kommunizieren .
Captain Man
@CaptainMan: Sicher, aber nehmen wir an, Sie haben diese einfache Funktion: fib(n)(Implementierung der Fibonacci-Serie). Sie möchten diese Implementierung nicht in jedem Microservice wiederholen. Das gehört zu einer utilsBibliothek (versioniert, für Features und Bugfixes). Das ist kein verteilter Monolith, das ist nur eine Schicht gemeinsamer Funktionalität. Meine Frage ist, wie ich mit dieser Ebene auf Implementierungsebene umgehen soll.
Dangonfast
Unsere Microservices verfügen über gemeinsam genutzte Bibliotheken, um sicherzustellen, dass sie mit allen anderen Microservices in unserem System auf dieselbe Weise kommunizieren. Ich bin mir nicht sicher, wie das mit nicht gemeinsam genutzten Bibliotheken möglich wäre. Zumindest würde jeder einige XML / JSON / etc-Manipulationsbibliotheken benötigen. Ich habe diese Präsentation noch nicht gesehen, aber hatten Sie eine spezifischere Bedeutung von "gemeinsam genutzte Bibliothek" im Sinn als die, an die ich denke?
Ixrec
1
@ jeckyll2hide Wir verwenden C ++, aber unsere Infrastruktur hierfür entspricht in etwa Ihrem zweiten Aufzählungspunkt: Separates Repo, jeder deklariert seine Abhängigkeiten, Standard-Build-System, das weiß, wie diese Abhängigkeiten zur Build-Zeit gefunden werden können usw.
Ixrec
1
Ich fühle mich wie ein Dummy. Bei Ihrer Frage geht es nicht wirklich um die gemeinsame Nutzung von Bibliotheken durch Microservices, sondern darum, wie Sie die Bibliotheken Ihres Teams mit dem Team teilen können. Ich weiß genug darüber, um eine Antwort zu schreiben.
Captain Man

Antworten:

5

Ihre zweite Option ist definitiv der richtige Weg. Brechen Sie allgemeine Bibliotheken auf und installieren Sie sie auf Ihrem lokalen PyPi-Server.

Option 1 ist schrecklich, da es schwierig sein wird, Verbesserungen an den Bibliotheken an andere weiterzugeben, die sie verwenden könnten.

Option 3 ähnelt Option 1.

Das übliche Muster besteht darin, Jenkins so einzurichten, dass beim Drücken auf den Master eines Bibliotheks-Repos ein Python-Build ausgeführt und automatisch in das PyPi-Repo hochgeladen wird. Sobald Sie dieses Build-Skript geschrieben haben, müssen Sie sich nie mehr darum kümmern, Bibliotheken zu verpacken und manuell auf PyPi hochzuladen. Mit dieser Option sind alle Bibliotheksaktualisierungen sofort verfügbar und können möglicherweise auf andere Microservices aktualisiert werden.

Das Einrichten eines eigenen PyPi-Servers ist sehr einfach. Ich mag diesen Leitfaden

Tommy
quelle
1
Ich bin damit einverstanden, dass Option 2 die beste ist, aber Option 3 mit den Submodulen hat viel mehr mit Option 2 gemeinsam als Option 1.
8bittree
@ 8bittree: Ja, Option 3 ähnelt Option 2, aber der Git-Server (die "zentrale" Fernbedienung) ist der Paketverteilungsmechanismus. Einerseits wird git für etwas verwendet, das nicht erwähnt wird (Abhängigkeitsmanagement), andererseits wird die Anzahl der Komponenten reduziert (kein privates PyPi erforderlich)
dangonfast
2

Kein Python-Typ, aber der PyPi-Server scheint die beste Option zu sein. Ein schnelles Googeln sieht aus wie ein Nexus-Repo für die Java-Gläser des Teams.

Wirklich, solange es in einer Art zentralem Repository (im Büro / Team) bereitgestellt wird, mit dem das Abhängigkeitsmanagement-Tool Ihrer Wahl arbeiten kann (von dem gelesen und bereitgestellt wird), ist es eine gute Option.

Option 1 ist wirklich das Schlimmste. Sie sollten sich niemals manuell mit Abhängigkeiten befassen müssen. Es ist nervtötend. Im College, bevor ich von Maven wusste und als ich dachte, Git sei zu kompliziert, haben wir alles manuell gemacht, vom Zusammenführen des Codes aller über das Einrichten von Klassenpfaden bis hin zum Abrufen von Abhängigkeiten. Es war ein Schmerz, ich würde ernsthaft nicht wollen, dass jemand auch nur einen Bruchteil dieser Probleme durchmacht, insbesondere in einem Arbeitsumfeld, in dem Effizienz wichtig ist.

Option 3 würde wahrscheinlich gut funktionieren, hat jedoch keine wirklichen Vorteile gegenüber einem lokalen PyPi (abgesehen davon, dass es möglicherweise einfacher einzurichten ist, aber die Vorteile eines echten Abhängigkeitsmanagementsystems sind einfach viel besser).

Captain Man
quelle
1

Zunächst einmal wird es immer schwierig sein, einen Monolithen in Mikrodienste aufzuteilen. Eine Idee dazu finden Sie unter Dezentrales Datenmanagement - Kapselung von Datenbanken in Microservices .

Das heißt, es gibt mehrere Rezepte, wie man es relativ vernünftig macht. Einer von ihnen ist http://12factor.net/ . Das würde sagen, dass Sie jede Bibliothek und Anwendung unabhängig pflegen und dann Abhängigkeiten explizit verwalten sollten. Wenn Sie diesen Weg gehen, empfehle ich STARK, dass Sie einen einfachen Befehl haben, der alle Abhängigkeiten auf den aktuellen Stand aktualisiert und ihn regelmäßig für jeden Mikrodienst ausführt. Es ist wichtig, einen vernünftigen Release-Prozess zu haben, bei dem Sie Versionen von Bibliotheken in der Produktion sperren. Sie möchten jedoch wirklich, wirklich , wirklich nicht in einer Position sein, in der Abhängigkeiten veralten und Sie nicht wissen, was da draußen ist.

Konzentrieren Sie sich auch darauf, Ihre Hintergrundbibliotheken so eng und fokussiert wie möglich zu gestalten. Es wird immer eine natürliche Anziehungskraft geben, Dinge zu Kernbibliotheken hinzuzufügen, um sie einfach zu teilen. Wenn Sie dies tun, ziehen Sie schnell den gesamten Ball vorhandener Spaghetti in gemeinsam genutzte Bibliotheken und kehren effektiv zu dem Chaos zurück, das Sie jetzt haben. Es ist daher besser, den anderen Weg zu stark zu korrigieren.

Übrigens
quelle
0

Sie sollten in der Lage sein, ohne Server zu arbeiten, indem Sie direkt von einer Python-Paketabhängigkeitsdatei auf die privaten GitHub-Repos zeigen, die die Bibliotheken enthalten. Pipenv und Poet unterstützen dies, glaube ich.

Hundewetter
quelle