<img height="1" width="1" style="display:none;" alt="" src="https://px.ads.linkedin.com/collect/?pid=1195114&amp;fmt=gif">
Close
HOME
/
Muster der Cloud-Architektur

Muster der Cloud-Architektur

22 September 2022, last update 22 September 2022 7 min read

Wie kann man Arbeit von Mendix nach Azure verlagern?

Als jemand, der seit mehreren Jahren mit Mendix arbeitet, bin ich mir der Grenzen des Mendix-Cloud-Angebots sehr bewusst. Es ist starr, teuer und bietet sehr wenig Raum für Anpassungen. Als ich vor mehr als zwei Jahren zum Team der smart digital factory stieß, beschlossen wir, die Rechenlast auf einen anderen Cloud-Anbieter zu verlagern, wo wir mehr Kontrolle und Flexibilität haben. Seitdem haben wir einige Schlüsselkomponenten der Fabrik erfolgreich in die Azure Cloud migriert.

In diesem Blog-Beitrag möchte ich mitteilen, wie wir dies erreicht haben, und einen "Leitfaden" für andere Entwickler anbieten, die ihre Arbeitslasten in die Cloud verlagern möchten. Zu Beginn möchte ich die grundlegenden Konzepte vorstellen.

Grundlagen der Cloud und Azure

Die Grundidee der Cloud besteht darin, dass Cloud-Anbieter wie Amazon, Microsoft oder Google ihre Server an andere Unternehmen und Einzelpersonen vermieten, anstatt sie zu kaufen, was mit hohen Vorlaufkosten verbunden ist. Im Laufe der Jahre hat sich dieser Grundgedanke weiterentwickelt, so dass die Anbieter heute neben dem Leasing von Hardware auch viele andere Produkte und Dienste anbieten. Einige beliebte und wichtige Dienste von Azure sind:

  • virtuelle Maschinen - so einfach wie möglich, volle Freiheit, alles zu installieren und auszuführen
  • Webapp - Verwaltete Webapp-Umgebung mit Unterstützung für viele Sprachen: Java, Nodejs usw.
  • Funktionen - Serverloses Angebot, das automatisch skaliert und nur minimalen Code erfordert
  • Blob-Speicher - für die Speicherung großer Dateien (>1 MB) wie Audio, Bilder und Video
  • Warteschlangen-Speicher - Senden von Kurznachrichten für Erzeuger-Verbraucher Szenarien
  • Service Bus - ähnlich der Warteschlange, aber schneller und mit besseren Garantien

Extra (im Beitrag nicht verwendet, aber gut zu wissen):

  • Tabellenspeicher - skalierbarer dokumentenbasierter Speicher (z.B. MongoDB), nicht als Haupt-DB geeignet
  • kubernetes - verwalteter Cluster, ideal in Kombination mit VMs

Die meisten Dienste werden nach dem Pay-as-you-go-Prinzip abgerechnet, d. h., die Kunden zahlen nur für die Zeit, in der der Dienst läuft. Im Allgemeinen kann jeder Dienst jederzeit gestartet und gestoppt werden.

Einige wichtige Gründe für die Verlagerung von Berechnungen in die Cloud sind:

  • Skalierbarkeit und Elastizität - schöne Worte, um zu sagen, dass die App in der Lage ist, auf Laständerungen zu reagieren und sich anzupassen, z. B. auf mehr Benutzeraktivität. Stellen Sie sich vor, eine Komponente in Ihrer Anwendung stößt an ihre Grenzen (oder wird diese voraussichtlich erreichen) und eine höhere Belastung würde einen Leistungsabfall oder Schlimmeres verursachen. In der Cloud können wir die Vorteile ihrer Dienste und ihrer umfangreichen Infrastruktur nutzen, um diese Komponente nach Bedarf und auch unabhängig vom Rest unserer Anwendung zu skalieren.
  • Kontrolle über die Umgebung - die Mendix-Plattform bietet nur sehr begrenzte Kontrolle über den Server, auf dem die App läuft. Es ist zum Beispiel nicht möglich, eine Binärdatei, eine Betriebssystembibliothek, eine bestimmte Version von Java oder eine andere Sprache wie Node zu installieren. Es ist nicht einmal möglich, die Datenbank zu konfigurieren. Bei anderen Cloud-Diensten, insbesondere bei VMs, aber auch bei Funktionen und bis zu einem gewissen Grad bei Web-Apps, gibt es mehr Freiheit, Dinge zu konfigurieren und zusätzliche Programme zu installieren.
  • Kosten - das Hosting der Mendix-Plattform kann recht teuer sein und in bestimmten Fällen kann es kosteneffizient sein, Komponenten, die viel Last erzeugen, in die Cloud zu verlagern. Dies ist vor allem dann der Fall, wenn Komponenten für kurze Zeit viele Ressourcen benötigen oder einer variablen Last unterliegen.

VMs vs. Web-App vs. Funktion: Wie man sich entscheidet

Dies sind die wichtigsten Rechendienste. Im Folgenden finden Sie eine kurze Faustregel, wann Sie welchen Dienst verwenden sollten:

  • Funktion - verwenden Sie diese für kurze, asynchrone Arbeitslasten, bis zu 10 Minuten
  • WebApps - für langlaufende oder synchronisierte Arbeitslasten, bei denen die Reaktionszeit entscheidend ist
  • VMs - wie WebApps, aber wenn zusätzliche Binärdateien oder Bibliotheken benötigt werden

Sowohl Funktionen als auch WebApps sollten gegenüber VMs bevorzugt werden. Bei ihnen ist es nicht notwendig, z. B. Java oder Node zu installieren, und es reicht aus, den Code der Anwendung bereitzustellen. Außerdem sind die wichtigsten Aspekte wie Skalierbarkeit, Elastizität und Verfügbarkeit bereits standardmäßig vorhanden oder können mit einem einzigen Mausklick aktiviert werden.

Während VMs und WebApps die ganze Zeit "an" sind, auch wenn es keine Arbeit zu erledigen gibt (und entsprechend abgerechnet werden), sind Funktionen eher wie die Sandbox von Mendix. Wenn es keine Anfragen gibt, geht die Funktion in den Schlaf. Sobald eine Anfrage eintrifft, wird die Funktion "geweckt", um die Anfrage zu bedienen. Das bedeutet, dass es deutlich günstiger sein kann, eine Funktion zu benutzen, je nachdem wie oft sie benutzt wird. Wie bei der Mendix-Sandbox kann es jedoch eine Weile dauern, bis die Funktion aufgeweckt wird, weshalb sie sich nicht für schnelle Aufrufe eignet, bei denen die Antwortzeit unter einer Sekunde liegen muss.

Dies kann durch eine sogenannte "Warmstart"-Funktion umgangen werden, was bedeutet, dass eine Instanz der Funktion immer läuft und bereit ist, Anfragen zu bedienen. Dies ist natürlich mit höheren Kosten verbunden. Weitere Einzelheiten finden Sie unter https://azure.microsoft.com/nl-nl/blog/understanding-serverless-cold-start/

Genug der Theorie für den Moment. Schauen wir uns nun einige reale Beispiele an.

Beispiel A: ATS-Läufer

Der ATS-Runner ist eine Komponente in ATS, die die Ausführung einzelner Testfälle übernimmt und die Ausführung von Testsuiten orchestriert. Wir verlagern ihn in die Cloud, damit wir ihn unabhängig von der Mendix-Plattform skalieren können. Sie stieß bereits an ihre Grenzen und aufgrund einer geplanten neuen Funktion erwarteten wir, dass sie nicht mehr mit akzeptabler Leistung arbeiten kann, wenn sie nicht in die Cloud verlegt und hochskaliert wird.

Wir entschieden uns für eine Web-App anstelle einer Funktion, weil:

  1. ein einzelner Job bis zu einigen Stunden dauern kann.
  2. der Ressourcenbedarf eines Auftrags schwer vorhersehbar ist. Einige Aufträge sind sehr klein, während andere viel Speicher und CPU benötigen, was sehr teuer werden kann. Mit einer Webapp haben wir eine bessere Kontrolle darüber, wie die Aufträge abgeholt werden, um die Ressourcen eines Rechners optimal zu nutzen.

Beispiel B: Modellabruf

Diese Komponente verwendet eine node.js-Bibliothek (MendixSDK), um auf eine bestimmte API zuzugreifen und deren Daten zu verarbeiten. Dies wurde in der Cloud implementiert, da wir in der Mendix-Laufzeitumgebung keine NodeJS-Skripte ausführen konnten. Im Gegensatz dazu konnten wir in der Cloud jede beliebige Sprache verwenden, die geeignet war. Wir haben uns hier für eine Funktion entschieden, weil:

  1. der Abruf durchschnittlich ein paar Minuten dauert, also in die 10 Minuten passt
  2. sie asynchron sein kann und wir nichts verlieren, wenn wir ein paar Sekunden länger warten.

Allgemeine Architekturmuster

Nachdem Sie sich für eine Funktion oder eine Webapplikation entschieden haben, müssen Sie herausfinden, wie Sie diese mit Ihrer Mendix-Applikation verbinden können. Auch hier hilft es, sich ein konkretes Beispiel anzusehen, wie den ATS Runner.

Eine einfache hybride Architektur für den ATS-Runner könnte wie folgt aussehen:

common-architecture-patterns

Nach dem KISS-Prinzip könnten wir die Runner-Komponente (die ein Stück Java-Code ist) mit einem Spring-Container (Server-Framework für Java) umhüllen und als Web-App in Azure hosten. Die Kommunikation zwischen der Hauptkomponente und dem Läufer würde nun über HTTP statt direkt auf demselben Rechner über Methodenaufrufe erfolgen. Dies ist der minimale Aufwand, um eine Komponente in die Cloud zu verlagern.

Auf den ersten Blick ist dies einfach, bis man erkennt, dass weder das Internet noch die beiden Komponenten zu 100 % zuverlässig sind. Einige der Dinge, die schief gehen können, sind:

  • Remote Runner ist unerreichbar - die Auftragsanfrage könnte verloren gehen.
  • Die ATS-Zentrale ist nicht erreichbar - die Protokolle werden nicht zugestellt.
  • Das Internet ist unzuverlässig - Aufträge oder Protokolle können verloren gehen, mehrfach oder in falscher Reihenfolge eintreffen.

Dies sind alles lösbare Probleme. Wir könnten Wiederholungen einführen, um sicherzustellen, dass Nachrichten nicht verloren gehen, Bestätigungen, um sicherzustellen, dass sie bearbeitet werden, wir könnten eine Art von Sequenznummerierung einführen, um die Reihenfolge zu gewährleisten, und Idempotenz-Token, um Duplikate zu verhindern. Aber all dies würde unseren Code verkomplizieren und hat nichts mit unserer Geschäftslogik zu tun. Es hört sich wirklich nach einem übergreifenden Konzert in unserem Tech-Stack an, das systemisch angegangen werden sollte, anstatt an jedem Integrationspunkt mehr Code auf das Problem zu werfen.

Hier kommen die anderen Azure-Services wie z. B. Storage ins Spiel.

Vorteile von Azure Queue und Service Bus

Durch die Verwendung eines Warteschlangen-Speichers oder eines Service-Busses können viele der oben genannten Probleme beseitigt werden:

  • Verfügbarkeit - Azure-Warteschlangen haben eine sehr hohe Verfügbarkeit, so dass Nachrichten nicht verloren gehen. Azure Storage SDKs haben einen Wiederholungsmechanismus und alle Arten von Fehlerbehandlung eingebaut.
  • Garantierte Zustellung - der Dienst selbst garantiert, dass eine Nachricht mindestens einmal (und höchstens einmal) zugestellt wird, auch wenn es mehrere Zuhörer/Konsumenten gibt.
  • Wiederholungsversuche - sind in den Warteschlangendienst eingebaut. Jedes Mal, wenn eine Nachricht aus der Warteschlange gelesen (gepoppt) wird, muss der Verbraucher sie löschen, sobald er sie vollständig verarbeitet hat. Wenn dieses Löschsignal nicht empfangen wird, fügt Azure die Nachricht nach einer konfigurierbaren Zeitspanne automatisch wieder in die Warteschlange ein. Dies kann für eine konfigurierbare Anzahl von Malen wiederholt werden. Sehr alte Nachrichten können auch automatisch gelöscht werden, indem eine Time-to-Live-Eigenschaft verwendet wird.
  • Zustellungsreihenfolge - Der Service Bus garantiert darüber hinaus die Reihenfolge der Zustellung pro Sitzung, wobei eine Sitzung ein benutzerdefiniertes Konstrukt ist. Im Falle von ATS ist eine Session ein Job. Die Protokolle eines Auftrags werden der Reihe nach zugestellt, während die Protokolle verschiedener Aufträge in beliebiger Reihenfolge parallel zugestellt werden können.

Aber warten Sie, es gibt noch mehr:

  • Ratenbegrenzung - wenn ein Verbraucher über verfügbare Ressourcen (RAM und CPU) verfügt, kann er mehr Nachrichten aus der Warteschlange lesen, andernfalls kann er eine Pause einlegen, bis wieder Ressourcen verfügbar sind. Der Produzent kann beliebig viele Nachrichten in die Warteschlange schreiben und muss sich nicht um die Kapazität des Konsumenten kümmern.
  • Lastausgleich - eine Warteschlange/ein Service-Bus kann mehrere Zuhörer haben. So kann er als selbstorganisierender Lastausgleich fungieren. Wenn ein Konsument an seine Ressourcengrenze stößt, kann er das Lesen von Nachrichten aus der Warteschlange unterbrechen und sie von anderen Konsumenten abholen lassen.

Grenzen von Warteschlange und Servicebus

Bei der Arbeit mit Warteschlangen ist jedoch nicht alles rosig. Die wichtigste Einschränkung ist, dass die Arbeit mit Warteschlangen die Dinge verlangsamen kann. Dieser Ansatz ist also nur dann geeignet, wenn die Antwortzeiten nicht das Hauptanliegen sind und Verzögerungen von ein paar hundert Millisekunden toleriert werden können. Insbesondere die Warteschlange kann erhebliche Verzögerungen aufweisen, und obwohl der Service-Bus in dieser Hinsicht viel besser ist, sind beide immer noch langsamer als die direkte HTTP-Kommunikation.

Eine weitere wichtige Einschränkung ist, dass die Nachrichtengröße für Warteschlangen maximal 64 KB (256 mit Premium) und für den Servicebus maximal 256 KB (1 MB) mit Premium beträgt. Das ist nicht schlimm, aber ein einzelnes Bild in ATS ist leicht größer als das. Um diese Einschränkung zu überwinden, werden Warteschlangen und Service-Bus oft mit Blob-Speicher kombiniert. In unserem Fall lädt der Läufer also Dateien (Bilder) in den Blob-Speicher hoch und sendet dann die ID (URL) der hochgeladenen Datei in einer Warteschlangennachricht. ATS Main liest die Informationen aus der Warteschlange und lädt die Datei nach Bedarf herunter.

Wenn wir all dies miteinander kombinieren, erhalten wir die folgende Architektur:

ATS-architecture

Dies kann auf jede Mendix-Anwendung und eine in der Cloud laufende Komponente verallgemeinert werden.

mendix-cloud

In diesem Diagramm sehen wir, dass die Mendix-Laufzeitumgebung Anfragen an eine Anfragewarteschlange (oder einen Servicebus) sendet. Zusätzlich werden große Daten, die als Teil der Anfrage benötigt werden, vorher in einem Blob-Storage gespeichert und in der Nachricht über ihre URL verlinkt.

Die Webapp oder Funktion in der Cloud liest die Anfragen aus der Warteschlange und verarbeitet sie.

Das Ergebnis wird dann an eine Ergebniswarteschlange gesendet. Auch hier können weitere Daten im Blob-Storage gespeichert, in der Nachricht verlinkt und später von der Mendix-Laufzeit abgerufen werden, um z.B. in der Benutzeroberfläche verwendet zu werden.

Abschließend möchte ich noch anmerken, dass, auch wenn der Beitrag über Azure spricht, diese grundlegenden Dienste Teil des Angebots aller gängigen Cloud-Anbieter sind. Die obige Architektur kann also auch auf andere Clouds angewandt werden, wahrscheinlich durch einfaches Ersetzen der Labels.

Ich hoffe, dass Ihnen dieser Beitrag gefällt und dass er Ihnen hilft, bessere und skalierbarere Anwendungen zu entwickeln!

START TODAY

Ready to accelerate your digital transition?

Get in touch Get in touch
Andrej Gajduk Andrej Gajduk is a consultant at Mansystems with over 7 years of experience in software development. Currently, he is a lead developer for Application Test Suite.

Related articles

Lesen Sie die neuesten Nachrichten, Artikel und Updates von CLEVR auf LinkedIn
Erhalten Sie persönliche Nachrichten und Updates in Ihrem Posteingang