Deployment von "micro"-Services

Hi,

ich weiß, Microservices sind gerade im Trend und eigentlich trifft der Begriff auf meinen Anwendungsfall nicht zu.

Ich habe eine Webanwendungen, die ich gerne in drei kleinere Webanwendungen unterteilen möchte.
Diese sollen auf der selben Datenbasis arbeiten, haben aber andere Berechtigungen und sehen unterschiedliche Bereiche der DB.
Die Frage ist nun, wie man das Deployment am besten gestaltet. Drei (bzw. vier, wenn die Datenbank auf einem separaten System läuft) separate Server zu verwenden kommt aus Kostengründen (vorerst) nicht in Frage. Etwas kostengünstiger wäre es, mehrere IP-Adressen zu verwenden, und diese an die verschiedenen Webanwendungen zu binden.
Ich hatte bereits damit herumexperimentiert, alle drei Anwendungen in einem Container laufen zu lassen, bekam aber Schwierigkeiten mit den Basispfaden, die durch verschiedene, eigentlich überflüssige, Präfixe hässlich wurden.
Ich möchte eigentlich gerne Embedded-Tomcat-Instanzen verwenden, die jeweils eine Teilanwendung darstellen.

Wie sehen gängige Lösungen für vergleichbare Szenarien aus? Hat jemand Tipps, wie so ein Deployment zu gestalten wäre?

Viele Grüße
Christian

Was war das für ein Container? Der Begriff wird heute ja für so ziemlich alles verwendet.

Ich würde (bis auf die DB vielleicht) in drei Docker Container werfen und sie mit Compose orchestrieren, kann aber sein dass ich mir das zu einfach vorstelle.

Ein tomcat-ServletContainer :wink: Also nichts in Richtung Virtualisierung.

Sind Docker-Container nicht etwas overkill? Wie sieht es mit dem Overhead aus?

Ich würde dann irgendwann gerne auf AWS EC2-Instanzen setzen und dort natürlich eine möglichst kleine Instanz nehmen.

Das kann ich ganz ehrlich noch nicht so richtig einschätzen. Wir spielen mit Docker zur Zeit in Dev und Test herum, haben den Schritt auf Prod aber noch nicht gemacht.

Von der Performance her habe ich da bisher in den Staging Umgebungen keine schlechten Erfahrungen gemacht, unsere Anwendungen hängen aber auch zu 99% im Intranet und kriegen sowieso nicht viel Last ab. Theoretisch sollte Docker ja wesentlich leichtgewichtiger sein als dedizierte VM, da kommt es aber wohl auf den Anwendungsfall an.

Wenn die Tomcat Lösung nicht gegriffen hat, weil es Probleme mit den Basispfaden gab, sollte sich das ja theoretisch entweder über Code oder geschicktes Proxyaing bei einem vorgeschalteten Apache / nginx lösen lassen, oder?

Im Prinzip brauchst Du kein Docker. Einen messbaren Overhead konnte ich allerdings bisher nicht feststellen. Der Vorteil ist, dass Du mit Docker Compose alles richtig orchestieren kannst.

Ansonsten kann eine Amazon Instanz recht schnell teuer werden. Es gibt diverse Anbieter, die recht günstig sind. Ich nutze z.B. die VPS von OVH. Da fange ich meist mit einer kleinen Instanz an und bringe alles zum Laufen. Diese Instanzen lassen sich aufstocken.

Mit einem vernünftigen Webserver wir nginx oder Apache sollte es auch ohne Contextpfade vernünftig laufen. Was waren hier Deine Probleme?

Dass die EC2-Instanzen schnell teuer werden können, habe ich auch festgestellt. Die Vorteile sind, dass die Instanzen austauschbar und skalierbar sind. Gerade in der Anlaufphase ist mir dieser Aspekt wichtig, vor allem, wenn man welche ohne Vertragslaufzeit (also on-demand-Instanzen) wählt.
Ich habe allerdings auch zwei dedizierte, recht schwachbrüstige Server, die ich vorerst zum Testen einsetze.

Mit einem Reverse-Proxy habe ich auch schon geliebäugelt. Problematisch hierbei ist das path-rewriting, was auf dem Rückweg auch auf dem generierten HTML-/XML-/JSON- oder sonstigen Seitenquellcode angewendet werden muss. Ein Mismatch zwischen dem in der Webanwendung verarbeiteten und der vom Nutzer aufgerufenen URL stellt sich als problematisch und fehlerträchtig dar.
Die Webanwendung(en) musste(n) auf unterschiedlichen Basispfaden arbeiten, weil der ServletContainer den aufgerufenen Hostnamen nicht als Auswahlkriterium für das verarbeitende Servlet weitergibt (das lässt die Spezifikation iirc auch nicht zu).

Aber ist nicht genau DAS der Einsatzzweck von ProxyPass und ProxyPassReverse?

Ja, das würde ich auch so sehen. Ohne einen solchen Webserver würde ich keine Anwendung betreiben wollen.

Zumindest die VPS Instanzen bei OVH sind monatlich kündbar und ab 3,50 Euro direkt nutzbar. Zuvor war ich bei Hetzner, die hatten ähnliche Angebote. So ins Geld geht das nicht. :slight_smile:

Ja, genau das ist der Anwendungsfall. Ich traue dem nur nicht so richtig über den Weg. Vielleicht sind meine Vorbehalte unbegründet, aber ProxyPassReverse kann doch gar nicht richtig funktionieren.

Beispiel: bei einem REST-Service werden Strings folgendermaßen codiert: s:<length><content>. Nun gebe ich die URL zu einer anderen Ressource meiner Webanwendung weiter. Die URL wird wohl noch korrekt ersetzt, aber den <length>-Parameter kann sie ja nicht anpassen.

Selbiges gilt auch für den Content-Length-Header, wobei der soweit standardisiert ist, dass der Apache / nginx / lighttpd / … den korrekt umrechnen dürfte.

Was ist mit Emails, die von der Webanwendung versandt werden? Da kann der ReverseProxy naturgemäß nicht greifen.

Wie geht ihr mit diesen Problemen um?

Bei meinen Webanwendungen liegt meistens ein Property in einer Config, welches die externe URL beschreibt. Das habe ich auch als Best Practice bei so ziemlich allen Kundenprojekten gesehen.

Dein Beispiel mit dem REST Service verstehe ich nicht, mod_proxy kümmert sich natürlich auch um das Rewriting von Parametern. Geht es dir darum, HATEOAS typisch Links für Operationen in der Payload mitzusenden? Für URL die in Emails gesendet werden, greife ich ebenfalls auf die Adresse in der Config zu.

Klar ist das eine weitere Konfig die du ansonsten nicht benötigst, aber spätestens wenn ein Load Balancer vor zwei Instanzen geschaltet würde, wäre es mit der spezifischen Tomcat URL ja eh vorbei.

Hört sich plausibel an.

Genau darum geht es mir, ja. Ob das ein realer Anwendungsfall sein wird, weiß ich nicht. Und insbesondere, ob die Daten tatsächlich so codiert werden, wie angegeben, ist ebenfalls fraglich. Im Header, bei der JSON oder XML wäre das ja kein Problem.

Ich denke, mit der Konfigurationslösung werde ich mal mein Glück versuchen. Die Emails sind bisher das einzige Szenario, welches ich als wirklich problematisch ansehe. Ich lasse die URLs in der Regel aus den Controllern generieren (Spring), diesbezüglich habe ich aber auch schon Experimente gemacht, damit dabei die richtige URL rauskommt.

Bzgl. HATEOAS gebe ich immer nur den relativen Pfad ohne Domain an. Das sparrt mir dort eine Konfiguration und die App ist nur lose mit der Domain gekoppelt.

1 „Gefällt mir“

Das würde ja besonders gut klappen, wenn die Teilanwendungen einfach nur auf unterschiedlichen Ports lauschen würden.
Diese Lösung fühlt sich für mich schon ganz gut an :wink: Welche Stolperfallen es dann doch noch gibt, wird man dann sehen.