
Die Welt steht nicht still. Fortschritt bringt neue technologische Herausforderungen mit sich. Entsprechend den veränderten Anforderungen muss auch die Architektur von Informationssystemen weiterentwickelt werden. Heute werden wir über ereignisgesteuerte Architektur, Parallelität, Asynchronität und darüber sprechen, wie man all dies friedlich in Erlang integrieren kann.
Einführung
Je nach Größe des geplanten Systems und den Anforderungen wählen wir, die Entwickler, die Kommunikationsmethode innerhalb des Systems aus. In den meisten Fällen kann ein Broker-Modell, beispielsweise basierend auf RabbitMQ oder Kafka, eine praktikable Lösung für die Interaktion zwischen den Diensten sein. Doch manchmal sind der Ereignisfluss, das SLA und der Grad der Kontrolle über das System so beschaffen, dass vorgefertigtes Messaging nicht ausreicht. Natürlich kann man das System etwas komplizierter gestalten, indem man die Verantwortung für die Transportebene und die Bildung eines Clusters übernimmt, etwa durch die Verwendung von ZeroMQ oder nanomsg. Wenn das System jedoch über ausreichende Bandbreite und die Möglichkeiten eines Standard-Erlang-Clusters verfügt, bedarf die Einführung einer zusätzlichen Entität einer tiefgehenden Analyse und einer wirtschaftlichen Rechtfertigung.
Das Thema reaktiver verteilter Anwendungen ist recht umfangreich. Um im Format eines Artikels zu bleiben, konzentrieren wir uns heute nur auf homogene Umgebungen, die auf Erlang/Elixir basieren. Das Erlang/OTP-Ökosystem ermöglicht die Implementierung einer reaktiven Architektur mit minimalem Aufwand. Dennoch benötigen wir eine Schicht für den Nachrichtenaustausch.
Theoretische Grundlagen
Die Planung beginnt mit der Definition von Zielen und Einschränkungen. Das Hauptziel liegt nicht im Bereich der Entwicklung um der Entwicklung willen. Wir müssen ein sicheres und skalierbares Werkzeug erhalten, auf dessen Grundlage moderne Anwendungen verschiedener Ebenen erstellt und vor allem weiterentwickelt werden können: von Ein-Server-Lösungen, die eine kleine Zielgruppe bedienen, die sich später zu Clustern von bis zu 50-60 Knoten entwickeln können, bis hin zu Cluster-Föderationen. Das Hauptziel besteht somit darin, den Gewinn durch Reduzierung der Entwicklungskosten und der Betriebskosten des Endsystems zu maximieren.
Lassen Sie uns vier Hauptanforderungen an das Endsystem hervorheben:
- EEreignisorientierung.
Das System ist stets bereit, einen Strom von Ereignissen zu verarbeiten und die erforderlichen Maßnahmen zu ergreifen; - Mskalierbarkeit.
Einzelne Module können sowohl vertikal als auch horizontal skaliert werden. Das gesamte System sollte in der Lage sein, unbegrenztes horizontales Wachstum zu ermöglichen; - eFehlertoleranz.
Alle Ebenen und Dienste müssen automatisch bei Ausfällen wiederhergestellt werden können; - Garantierte Reaktionszeit.
Zeit ist kostbar, und die Benutzer sollten nicht zu lange warten müssen.
Denken Sie an das alte Märchen von „Der kleine Zug, der es schaffen konnte“, auch bekannt als „Der kleine Lokomotivführer“? Damit das geplante System erfolgreich aus der Prototypenphase herauskommt und fortschrittlich ist, muss sein Fundament die minimalen Anforderungen erfüllen. KONNTE.
Der Messaging-Ansatz als Infrastrukturwerkzeug und Basis für alle Dienste wird um einen weiteren Punkt ergänzt: die Benutzerfreundlichkeit für Entwickler.
Ereignisorientierung
Damit die Anwendung aus einem einzelnen Server Für einen Cluster muss die Architektur eine geringe Kopplung gewährleisten. Dieses Kriterium wird durch das asynchrone Modell erfüllt. Dabei kümmern sich Sender und Empfänger um die Informationslast der Nachricht, ohne sich um die Übertragung und die Routing innerhalb des Systems zu sorgen.
Skalierbarkeit
Skalierbarkeit und Effizienz der Systeme gehen Hand in Hand. Die Anwendungsbestandteile müssen in der Lage sein, alle verfügbaren Ressourcen optimal zu nutzen. Je effizienter wir die Rechenleistung einsetzen und je besser unsere Verarbeitungsmethoden sind, desto weniger Ausgaben haben wir für die Hardware.
Innerhalb einer einzelnen Maschine schafft Erlang eine hochgradig wettbewerbsfähige Umgebung. Das Gleichgewicht zwischen Konkurrenz und Parallelität kann durch die Wahl der verfügbaren Betriebssystem-Threads für die Erlang VM und der Anzahl der Scheduler, die diese Threads nutzen, bestimmt werden.
Erlang-Prozesse haben keinen gemeinsamen Zustand und arbeiten im nicht-blockierenden Modus. Dies sorgt für eine vergleichsweise niedrige Latenz und eine höhere Durchsatzrate als bei traditionellen Anwendungen, die auf blockierender Synchronisierung basieren. Der Erlang-Scheduler kümmert sich um eine faire Verteilung von CPU und IO, und da es keine Blockierungen gibt, kann die Anwendung selbst bei Spitzenlasten oder Ausfällen reagieren.
Auch auf Cluster-Ebene gibt es Probleme mit der Auslastung. Es ist wichtig, dass alle Maschinen im Cluster gleichmäßig belastet sind und das Netzwerk nicht überlastet wird. Stellen Sie sich vor: Der Benutzer-Traffic landet auf den eingehenden Load-Balancern (haproxy, nginx usw.), die die Anfragen so gleichmäßig wie möglich auf eine Gruppe verfügbarer Backends verteilen. Innerhalb der Anwendungsinfrastruktur ist der Dienst, der die benötigte Schnittstelle bereitstellt, nur die letzte Meile und muss eine Reihe anderer Dienste anfordern, um auf die ursprüngliche Anfrage zu reagieren. Interne Anfragen erfordern ebenfalls Routing und Lastverteilung.
Um Datenströme effektiv zu verwalten, muss Messaging Entwicklern eine Schnittstelle zur Steuerung der Routing- und Lastverteilung bereitstellen. Dadurch können Entwickler mithilfe von Microservice-Architekturen (Aggregator, Proxy, Chain, Branch usw.) sowohl Standard- als auch seltene Aufgaben lösen.
Aus geschäftlicher Sicht ist Skalierbarkeit ein wichtiges Instrument zur Risikosteuerung. Es ist entscheidend, die Kundenanforderungen optimal zu erfüllen und die vorhandene Hardware effizient zu nutzen:
- Durch den Fortschritt bei der Leistungssteigerung der Hardware wird diese nicht durch Softwareunzulänglichkeiten ungenutzt bleiben. Erlang lässt sich hervorragend vertikal skalieren und kann immer alle CPU-Kerne und den verfügbaren Speicher nutzen.
- In Cloud-Umgebungen können wir die Anzahl der Hardware entsprechend der aktuellen oder prognostizierten Last verwalten und SLA garantieren.
Ausfallsicherheit
Betrachten wir zwei Axiome: 'Fehler sind unzulässig' und 'Fehler werden immer auftreten'. Für Unternehmen bedeutet ein Softwareausfall Geldverlust und, was noch schlimmer ist, einen Rufschaden. Oft lässt sich ein Kompromiss zwischen potenziellen Verlusten und den Kosten für die Entwicklung fehlertoleranter Software finden.
Kurzfristig spart eine Architektur mit integrierter Fehlertoleranz Kosten für den Kauf teurer gebrauchsfertiger Clusterlösungen, die zudem Fehler aufweisen können.
Langfristig amortisiert sich eine ausfallsichere Architektur mehrfach im gesamten Entwicklungsprozess.
Messaging innerhalb des Codes bereits in der Entwicklungsphase ermöglicht eine detaillierte Abstimmung der Interaktionen zwischen den Komponenten im System. Dadurch wird die Reaktion auf und das Management von Fehlern vereinfacht, da alle verantwortlichen Komponenten die Fehler behandeln und das Gesamtsystem weiß, wie es nach einem Fehler automatisch in den Normalbetrieb zurückkehrt – by design.
Reaktionsfähigkeit
Unabhängig von Ausfällen muss die Anwendung auf Anfragen reagieren und die SLA erfüllen. Die Realität ist, dass Menschen nicht warten möchten, daher muss sich das Geschäft anpassen. Immer mehr Anwendungen erwarten eine hohe Reaktionsfähigkeit.
Reaktionsschnelle Anwendungen arbeiten nahezu in Echtzeit. Die Erlang VM funktioniert im Modus der weichen Echtzeit. Für bestimmte Bereiche wie den Aktienhandel, die Medizin und das Management von Industrieanlagen ist der Modus der harten Echtzeit entscheidend.
Reaktionsschnelle Systeme verbessern die Benutzererfahrung und sind für Unternehmen von Nutzen.
Vorläufiges Fazit
Bei der Planung dieses Artikels wollte ich meine Erfahrungen beim Erstellen eines Messaging-Brokers und beim Aufbau komplexer Systeme darauf basierend teilen. Doch der theoretische und motivierende Teil erwies sich als ziemlich umfangreich.
Im zweiten Teil des Artikels werde ich die Feinheiten der Implementierung von Austauschpunkten, Nachrichtenmustern und deren Anwendung erläutern.
Im dritten Teil betrachten wir allgemeine Fragen zur Organisation von Diensten, Routing und Lastverteilung. Wir werden über die praktische Seite der Skalierbarkeit und Fehlertoleranz von Systemen sprechen.
Ende des ersten Teils.
Foto .
Quelle: habr.com
