RX.control – Architektur

Dem Konzept der RX.control-Software, genauer der Infrastrukursoftware, liegt ein bestimmtes Architectural Design Pattern (Architekturmuster, Entwurfsmuster) zugrunde, das sich als felderprobt erwiesen hat - siehe Referenzen. Etwas akademisch wird es manchmal ein "System kommunizierender Zustandsautomaten" genannt.

Wie unter Einsatzfelder beschrieben, bezieht sich das Muster auf die Architektur einer verteilten Anwendung aus mehreren Prozessen, die miteinander kommunizieren und Daten austauschen. Das Konzept wird im folgenden Diagramm illustriert. Die Farben zeigen die Schichten aus dem Schichtenmodell an und verdeutlichen, wie die RX.control-Komponenten die Applikation untermauern.

 

Diagram RX.control Scheme

 

 

Die wesentlichen Charakteristika einer solchen Architektur sind:

  • Ein Applikationsprozess implementiert z.B. die Steuerung eines Gerätes, einen bestimmten Service oder eine Stufe einer Datenverarbeitungskette.
  • Mehrere solcher dedizierter Prozesse realisieren so auf modulare, ggf. verteilte Weise die Funktionalität des Gesamtsystems.
  • Die interne Logik eines Applikationsprozesses wird durch Ereignisse bestimmt, die als Nachrichten in einer Message Queue eintreffen und entsprechende Handlerfunktionen aufrufen. Eine Zustandsmaschine definiert und verwaltet die Betriebszustände des Prozesses, die durch diese Ereignisse getrieben wird.
  • Applikationsprozesse kommunizieren untereinander mit Messages, die Kommandos, Antworten oder Benachrichtigungen darstellen und vom Empfänger als Ereignisse behandelt werden.
  • Applikationsprozesse veröffentlichen Daten in einer zentralen In-Memory-Datenbank und lesen daraus Daten anderer Prozesse. Auch die initiale Konfiguration von Prozessen erfolgt auf diesem Weg. Prozesse können sich über Änderungen in der Datenbank benachrichtigen lassen.
  • Mit den Konzepten des Messagings und der Datenbank sind die Applikationsprozesse schwach gekoppelt. Der Kommando- und Datenfluss lässt sich so per Konfiguration anpassen ohne ein Neubauen der Applikation zu erfordern.
  • Eine zentrale Instanz - der Applikationsmanager - startet und konfiguriert das System der Applikationsprozesse, nachdem zentrale Dienste, wie die In-Memory-Datenbank, die Netzwerkkommunikation und das Logging initialisiert wurden.
  • Zur Laufzeit überwacht der Applikationsmanager das System.

 

Warum Prozesse statt Threads?

Anstatt mit mehreren Prozessen könnte man eine Applikation auch mit Multi-Threading konzipieren, wobei jedem Prozess ein Thread entspricht. Eine Multi-Prozess-Lösung hat jedoch Vorteile:

  • Das Bauen und Deployment eines Applikationssystems aus Prozessen ist modularer, gegenüber einer monolithischen und sehr großen Multi-Thread-Applikation; jedes Programm kann einzeln erstellt und installiert werden. Es kann auch ein einzelnes Programm z.B. zu Testzwecken gegen einen Stubprozess ausgetauscht werden, ohne die Applikation neu zu bauen.
  • Das Verwalten, Inspizieren, Debuggen, usw. von der Shell und Tools aus ist einfacher; Prozesse sind individuell zugänglich, während Threads zunächst im Innern von Prozessen verborgen sind.
  • Das Signalhandling einer Multi-Thread-Applikation ist schwierig bzgl. der Vorhersage und Kontrolle welchem Thread ein Signal zugestellt wird; es besteht eine starke Abhängigkeit vom Signal und von der Linux Kernelversion.
  • Jedem Prozess können individuelle Aufrufargumente mitgegeben werden.
  • Die Prozesspriorität und die Zuordnung zu einem CPU-Kern kann einfacher eingestellt werden, gegenüber dem komplizierteren Umgang mit User PID, Kernel PID und TGID für Threads.
  • Zudem benötigt ein Applikationsprozess häufig Hilfsthreads, z.B. für Timer oder Hintergrundaufgaben. In einer Applikation, in der auch alle Prozesse an sich als Threads angelegt sind, führt dies zu einer komplexen Threadhierarchie.

Unter Performance- und Ressourcenaspekten sind Prozesse und Threads unter Linux nur wenig verschieden. Aus Sicht des Kernels sind beide Ausprägungen "Tasks". Die Argumentation, dass zwischen Threads, die sich einen Adressraum teilen Interprozesskommunikation und -synchronisation, sowie Zugriff auf globale Variablen einfacher ist, wiegt nicht schwer. Alle IPC-Mechanismen sind auch zwischen Prozessen verfügbar und mit nur wenig Mehraufwand erreichbar, der zudem nur einmal in entsprechen Basisklassen von RX.control implementiert ist. Im Gegenzug entstehen bei der Verwendung von Threads Aufwände z.B. für die Verwendung von Thread Local Storage.

Daher setzt RX.control auf ein Multi-Prozess-Modell, womit einem Anwender die Vorteile an die Hand gegeben sind und kein erhöhter Aufwand entsteht, da die Infrastruktursoftware für dieses Modell die benötigten IPC-Mechanismen als Klassenbibliothek implementiert und als einfach zu verwendende API bereitstellt.