Lernpfad: Monolith in eine GKE-Anwendung umwandeln – Monolith modularisieren


Dies ist die zweite Anleitung in einem Lernpfad, in dem Sie erfahren, wie Sie eine monolithische Anwendung modularisieren und containerisieren.

Der Lernpfad besteht aus den folgenden Anleitungen:

  1. Übersicht
  2. Monolith verstehen
  3. Monolith modularisieren (diese Anleitung)
  4. Modulare App für die Containerisierung vorbereiten
  5. Modulare App containerisieren
  6. Anwendung in einem GKE-Cluster bereitstellen

Im vorherigen Tutorial Monolithische Anwendung verstehen haben Sie eine monolithische Anwendung namens Cymbal Books kennengelernt. Sie haben den Monolithen auf Ihrem lokalen Computer ausgeführt und festgestellt, dass verschiedene Teile des Monolithen über ihre Endpunkte miteinander kommunizieren.

In dieser Anleitung erfahren Sie, wie Sie den Monolithen in Module unterteilen, um ihn für die Containerisierung vorzubereiten. Sie müssen die Modularisierungsschritte nicht selbst ausführen, da der Code bereits für Sie aktualisiert wurde. Ihre Aufgabe ist es, der Anleitung zu folgen und die modulare Version der App im Repository zu untersuchen, um zu sehen, wie sie sich vom ursprünglichen Monolithen unterscheidet.

Kosten

Für diese Anleitung fallen keine Kosten an. Wenn Sie jedoch die Schritte in der letzten Anleitung dieser Reihe ausführen, fallen Kosten für IhrGoogle Cloud -Konto an. Die Kosten fallen an, sobald Sie GKE aktivieren und die Cymbal Books-App in einem GKE-Cluster bereitstellen. Diese Kosten umfassen Clustergebühren für GKE, wie auf der Preisseite beschrieben, und Gebühren für die Ausführung von Compute Engine-VMs.

Um unnötige Gebühren zu vermeiden, sollten Sie GKE deaktivieren oder das Projekt löschen, sobald Sie diese Anleitung abgeschlossen haben.

Hinweise

Bevor Sie mit dieser Anleitung beginnen, müssen Sie die erste Anleitung Monolith verstehen durchgearbeitet haben. In dieser Anleitung führen Sie die modulare Version von Cymbal Books auf Ihrem lokalen Computer aus. Dazu müssen Sie Ihre Umgebung bereits eingerichtet haben. Wenn Sie das erste Tutorial bereits durchgearbeitet haben, haben Sie ein GitHub-Repository geklont. Alle drei Versionen der Cymbal Books App befinden sich in diesem Repository in den folgenden Ordnern:

  • monolith/
  • modular/
  • containerized/

Prüfen Sie, ob sich diese Ordner auf Ihrem Computer befinden, bevor Sie fortfahren. Achten Sie außerdem darauf, dass die virtuelle Umgebung book-review-env aktiv ist. Wenn Sie eine Erinnerung zum Aktivieren benötigen, lesen Sie im ersten Tutorial den Abschnitt Virtuelle Umgebung erstellen und aktivieren. Durch die Aktivierung der Umgebung wird dafür gesorgt, dass die modulare Version der App alles hat, was zum Ausführen erforderlich ist.

Was ist Modularisierung?

In dieser Anleitung erfahren Sie, wie Sie die monolithische App modularisieren, um sie für die Containerisierung vorzubereiten. Bei der Modularisierung wird ein Monolith in eine modulare App umgewandelt. Wie Sie im vorherigen Tutorial gelernt haben, können die Komponenten eines Monolithen nicht unabhängig ausgeführt oder skaliert werden. Bei einer modularen App ist das anders: Ihre Funktionen sind in Module unterteilt, die unabhängig voneinander ausgeführt und skaliert werden können.

Obwohl Modularisierung und Containerisierung oft zusammen erfolgen, werden sie in dieser Reihe von Tutorials als separate Schritte behandelt, damit Sie die einzelnen Konzepte besser verstehen. In dieser Anleitung wird beschrieben, wie Sie einen Monolithen modularisieren. In einer späteren Anleitung wird erläutert, wie Sie die modulare App containerisieren.

Inkrementelle Modularisierung

In Produktionsumgebungen modularisieren Sie in der Regel jeweils eine Komponente. Sie modularisieren die Komponente, integrieren das Modul in den Monolithen und sorgen dafür, dass alles funktioniert, bevor Sie an der nächsten Komponente arbeiten. Dieser Hybridzustand, in dem einige Komponenten modularisiert sind, während andere Teil des Monolithen bleiben, wird als Mikrolith bezeichnet. In dieser Anleitung werden jedoch alle Komponenten der App gleichzeitig modularisiert, um ein vollständiges Beispiel für die Modularisierung einer App zu liefern.

Monolith modularisieren

In diesem Abschnitt erfahren Sie, wie der Monolith von Cymbal Books in separate Module aufgeteilt wurde. Es werden Schritte beschrieben, die Ihnen helfen, den Modularisierungsprozess zu verstehen, damit Sie ihn auf Ihre eigenen Apps anwenden können. Sie müssen diese Schritte in dieser Anleitung jedoch nicht ausführen, da das geklonte Repository bereits die modulare Version der App enthält:

  1. Unterschiedliche Funktionen der App identifizieren
  2. Module erstellen
  3. Kommunikation zwischen den Modulen aktivieren
  4. Jedem Modul nur Zugriff auf die benötigten Daten gewähren

Unterschiedliche Funktionen der App identifizieren

Der erste Schritt bei der Modularisierung des Cymbal Books-Monolithen besteht darin, seine Hauptfunktionen zu identifizieren. Im Beispiel der Cymbal Books-Anwendung hat der Monolith die folgenden vier unterschiedlichen Funktionen:

  • Startseite bereitstellen
  • Buchdetails bereitstellen
  • Buchrezensionen bereitstellen
  • Bereitstellung von Buchcoverbildern

Module erstellen

Wie Sie im vorherigen Tutorial gesehen haben, ist der Monolith eine einzelne Flask-App, die die vier Funktionen, die im vorherigen Abschnitt als Routenhandler identifiziert wurden, implementiert. Um die App zu modularisieren, nehmen Sie jeden Routen-Handler und fügen ihn in eine eigene Flask-App ein. Anstelle einer Flask-App mit vier Routen-Handlern haben Sie vier Flask-Apps, die jeweils einen einzelnen Routen-Handler enthalten.

Das folgende Diagramm veranschaulicht diese Transformation von einer einzelnen Flask-App in vier separate Flask-Apps:

Umwandlung des Monolithen in eine modulare App

In der modularen App wird jede Flask-App unabhängig ausgeführt und lauscht auf einem anderen Port (8080, 8081, 8082, 8083), wie im Diagramm dargestellt. Diese Einrichtung ist erforderlich, da Sie beim späteren Testen der modularen App in diesem Tutorial alle Module auf derselben Maschine ausführen. Jede App benötigt eine andere Portnummer, um Konflikte zu vermeiden.

Das Startseitenmodul hat zwei Aufgaben: Es stellt die Startseite bereit und kommuniziert mit den anderen Modulen, um Daten zu erfassen, die auf einer Webseite angezeigt werden müssen. Die anderen Module konzentrieren sich jeweils auf eine einzelne Funktion: die Bereitstellung von Rezensionen, Details oder Bildern. Diese Module kommunizieren nicht miteinander, sondern reagieren nur auf Anfragen des Startseitenmoduls.

Obwohl das Startseitenmodul eine zusätzliche Koordinierungsrolle hat, ist die App weiterhin modular, da Sie jedes Modul aktualisieren können, ohne dass sich dies auf die anderen Module auswirkt. Die einzelne große Flask-Anwendung wurde in vier Teile aufgeteilt, die jeweils einen bestimmten Teil der Anwendungsfunktionen abdecken.

Kommunikation zwischen den Modulen aktivieren

Nachdem Sie die Module erstellt haben, müssen Sie dafür sorgen, dass sie miteinander kommunizieren können. In der Cymbal Books App ist diese Kommunikationslogik bereits für Sie implementiert. Im Ordner modular/ des heruntergeladenen Codes sehen Sie, dass jede der Hauptfunktionen der App – Bereitstellung der Startseite, Buchdetails, Rezensionen und Bilder – als separate Flask-App implementiert ist. Jede dieser Apps definiert einen eigenen HTTP-Endpunkt und die Module kommunizieren, indem sie HTTP-Anfragen an diese Endpunkte senden.

Die Modularisierung des Cymbal Books-Monolithen war unkompliziert. Der Monolith hat genau definierte Komponenten, die als Routenhandler implementiert werden, und jeder Routenhandler hat einen genau definierten Endpunkt. Wenn diese Routen-Handler in separate Flask-Anwendungen verschoben werden, können sie weiterhin über ihre Endpunkte kommunizieren. Durch das einfache Platzieren der Routen-Handler in separaten Flask-Apps werden sowohl die Module erstellt als auch die Kommunikation zwischen den Modulen ermöglicht.

Ein gängiger Ansatz für die Kommunikation zwischen Modulen ist die Implementierung von REST APIs, die es Modulen ermöglichen, HTTP-Anfragen aneinander zu senden. So funktioniert es in Cymbal Books: In jedem Modul werden REST-Endpunkte mit den integrierten Tools von Flask definiert. Ein weiterer beliebter Ansatz ist gRPC, mit dem Module die Funktionen des jeweils anderen direkt aufrufen können.

Warum die Kommunikation in Cymbal Books so einfach ist

Jedes Modul in der modularen App ist eine separate Flask-Anwendung, die auf einem Webserver ausgeführt wird. Das Startseitenmodul stellt beispielsweise die Startseite bereit, das Modul für Buchdetails die Buchdetails. Die Kommunikation zwischen den Modulen ist unkompliziert, da Webserver für die Verarbeitung von HTTP-Anfragen und ‑Antworten konzipiert sind. Jedes Modul stellt Endpunkte bereit, über die andere Module Daten anfordern können.

Jedem Modul nur Zugriff auf die Daten gewähren, die es benötigt

Damit Sie den Monolithen richtig modularisieren können, müssen Sie dafür sorgen, dass jedes Modul nur auf die Daten zugreifen kann, die es benötigt. Dieses Prinzip, das als Datenisolation bezeichnet wird, ist ein wichtiger Bestandteil beim Erstellen einer wirklich modularen Architektur.

Ein häufiger Fehler bei der Modularisierung besteht darin, dass mehrere Module auf dieselben Daten zugreifen dürfen, z. B. auf eine einzelne Datenbank. Diese Art der Implementierung kann zu Problemen wie den folgenden führen:

  • Enge Kopplung: Wenn sich die Struktur der freigegebenen Daten ändert, z. B. wenn eine Datenbanktabelle umbenannt oder eine Spalte hinzugefügt wird, muss jedes Modul, das auf diese Daten angewiesen ist, aktualisiert werden. Durch eine geeignete Modularisierung lässt sich dieses Problem vermeiden.
  • Probleme mit der Fehlertoleranz: Wenn mehrere Module dieselbe Datenquelle verwenden, können Laufzeitfehler in einem Modul, z. B. ungültige Abfragen oder übermäßiger Traffic, andere Module beeinträchtigen. Ein Fehler in einem Teil des Systems kann zu Fehlern in anderen Teilen des Systems führen.
  • Leistungsengpässe: Eine einzelne, gemeinsam genutzte Datenquelle kann zu einem Engpass werden, der die gesamte Anwendung verlangsamt, wenn mehrere Module versuchen, mit ihr zu interagieren.

Um diese Probleme zu vermeiden, sollte jedes Modul eine eigene Datenquelle haben.

Wenn Cymbal Books eine Datenbank zum Speichern der Daten verwendet hätte, müssten Sie die Datenbank replizieren oder partitionieren, um die Datenisolation zu erzwingen und dafür zu sorgen, dass jedes Modul nur auf die Daten zugreift, die es benötigt. Bei der Replikation werden separate Kopien der Datenbank für jedes Modul erstellt, während bei der Partitionierung der Zugriff auf bestimmte Tabellen oder Zeilen eingeschränkt wird. Beide Ansätze verhindern, dass Module die Daten anderer Module beeinträchtigen.

Im folgenden Diagramm wird die Architektur der monolithischen Buch-App mit der modularen Architektur der Buch-App verglichen:

Ein Diagramm, das zeigt, wie die monolithische und die modulare Version der App Daten verarbeiten

Die Implementierung des Monolithen folgt nicht dem Prinzip der Datenisolation, da die Funktionen des Monolithen auf ein einzelnes data/-Verzeichnis zugreifen.

Im Gegensatz dazu wird in der modularen App ein gewisses Maß an Datenisolation erreicht, indem Daten in separate Verzeichnisse aufgeteilt werden und dafür gesorgt wird, dass jedes Modul nur mit den ihm zugewiesenen Daten interagiert:

  • Das Modul „Buchdetails“ ruft Daten nur aus dem Verzeichnis details_data/ ab.
  • Das Modul „Buchrezensionen“ ruft Daten nur aus dem Verzeichnis reviews_data/ ab.
  • Das Modul „Bilder“ ruft Daten nur aus dem Verzeichnis images/ ab.

In einer späteren Anleitung erfahren Sie, wie die Datenisolation durch Containerisierung der App weiter verbessert werden kann.

Was Sie gerade gesehen haben

In der Softwareentwicklung begegnen Ihnen häufig die Begriffe Mikrodienste und verteilte Systeme. In diesem Abschnitt wird erläutert, wie sich diese Begriffe auf die modulare Implementierung von Cymbal Books beziehen.

Mikrodienste

Mikrodienste sind autonome Module, die bestimmte Aufgaben ausführen. Diese Module kommunizieren über Schnittstellen wie Endpunkte mit anderen Modulen.

Jedes Modul in der modularen Version von Cymbal Books entspricht dieser Definition und kann daher als Mikrodienst bezeichnet werden. Wenn die modulare App in einem späteren Tutorial in einem Container bereitgestellt wird, kann der Code, der in einem Container ausgeführt wird, auch als Microservice bezeichnet werden, da es sich um denselben Code handelt, der in einem Modul ausgeführt wird.

Verteilte Systeme

Ein verteiltes System besteht aus unabhängigen Modulen, die über ein Netzwerk kommunizieren, um ein gemeinsames Ziel zu erreichen. Diese Module können auf verschiedenen Computern ausgeführt werden, arbeiten aber als ein einziges System zusammen.

Die modulare Cymbal Books App entspricht ebenfalls dieser Definition: Ihre Module werden unabhängig voneinander ausgeführt und tauschen Daten über HTTP aus, funktionieren aber zusammen als ein einzelnes System. Im nächsten Abschnitt führen Sie alle Module zur Vereinfachung auf einem einzelnen Computer aus. Das ist jedoch nicht erforderlich. Jedes Modul könnte genauso gut auf einem anderen Server ausgeführt werden. Daher kann die modulare Version der Cymbal Books App als verteiltes System eingestuft werden.

Modulare Implementierung testen

Nachdem Sie gesehen haben, wie der Cymbal Books-Monolith in eine modulare App umgewandelt wird, deren Module Flask-Apps sind, können Sie die Anwendung testen und sehen, dass jedes Modul unabhängig ausgeführt wird.

In dieser Anleitung führen Sie die Module auf demselben Computer aus. Sie können jedes Modul aber auch auf einem separaten Server ausführen. Da jedes Modul autonom ist, kann es über seine Endpunkte mit den anderen Modulen kommunizieren.

Umgebung einrichten

So bereiten Sie sich auf die Tests vor:

  1. Öffnen Sie in Ihrem Terminal das Verzeichnis modular im geklonten Repository:

    cd modular
    
  2. Achten Sie darauf, dass die virtuelle Umgebung book-review-env aktiv ist. Wenn Sie eine Erinnerung an die Aktivierungsschritte benötigen, lesen Sie den Abschnitt Virtuelle Umgebung erstellen und aktivieren.

Flask-Anwendung starten

Der Ordner /modular enthält ein Bash-Skript, mit dem alle Flask-Anwendungen gleichzeitig gestartet werden. Jedes Modul der App überwacht einen eindeutigen Port wie 8080 oder 8081:

  • Homepage-Flask-App (home.py): Port 8080
  • Flask-App für Buchdetails (book_details.py): Port 8081
  • Flask-App für Buchrezensionen (book_reviews.py): Port 8082
  • Images Flask-App (images.py): Port 8083

Jedes Modul muss auf einer eindeutigen Portnummer lauschen, da alle Module auf demselben Computer ausgeführt werden. Wenn sich jedes Modul auf einem anderen Server befände, könnte jedes Modul auf derselben Portnummer lauschen, ohne dass Portkonflikte entstehen.

Führen Sie das Bash-Skript mit diesem Befehl aus:

bash ./start_services.sh

Das Skript erstellt für jede Flask-App eine separate Logdatei (z. B. home.py.log, book_details.py.log), damit Sie Startprobleme leichter erkennen können. Wenn das Skript erfolgreich abgeschlossen wurde, wird folgende Meldung angezeigt:

All services have been started. Access the app at http://localhost:8080/

Jede Flask-App testen

Testen Sie die Module, indem Sie die folgenden URLs in Ihrem Browser aufrufen:

  • Startseite: http://localhost:8080/ zeigt die Startseite der modularisierten Cymbal Books-Anwendung an. Auf dieser Seite werden Buchdetails, Rezensionen und Bilder abgerufen, indem Anfragen an die anderen Module gesendet werden.
  • Buchdetails: http://localhost:8081/book/1 gibt die Details des Buchs mit der ID 1 zurück. Diese Antwort besteht aus JSON-Daten, die von der App formatiert und in einer für Menschen besser lesbaren Form dargestellt werden.
  • Buchrezensionen: http://localhost:8082/book/1/reviews ruft die Rezensionen für das Buch mit der ID 1 ab und gibt sie zurück. Die Rezensionen haben das JSON-Format. Das Startseitenmodul fordert diese Daten an und integriert sie in die Seite mit den Buchdetails.
  • Bilder: http://localhost:8083/images/fungi_frontier.jpg stellt das Buchcoverbild für Fungi Frontier bereit. Wenn die URL korrekt ist, sollte das Bild direkt in Ihrem Browser geladen werden.

Flask-Apps beenden

Wenn Sie die Tests abgeschlossen haben, beenden Sie alle Flask-Apps mit diesem Befehl:

kill $(cat home.py.pid book_details.py.pid book_reviews.py.pid images.py.pid)

Zusammenfassung

In dieser Anleitung haben Sie gelernt, wie Sie den Cymbal Books-Monolithen modularisieren. Der Prozess besteht aus den folgenden Schritten:

  1. Unterschiedliche Komponenten der App identifizieren
  2. Module erstellen
  3. Jedes Modul hat nur Zugriff auf die Daten, die es benötigt.

Anschließend haben Sie die modulare Implementierung auf Ihrem lokalen Computer getestet.

Nächste Schritte

Im nächsten Tutorial Modulare App für die Containerisierung vorbereiten erfahren Sie, wie Sie die modulare App für die Containerisierung vorbereiten, indem Sie die Endpunkte so aktualisieren, dass Kubernetes-Servicenamen anstelle von localhost verwendet werden.