-
Die vorliegende Erfindung betrifft ein Verfahren zur Kommunikation von Komponenten in einem Netzwerk, welches insbesondere ein verteiltes System bildet, umfassend verschiedene Komponenten, z. B. Control-Unit, Server, Datenbankmodul, Kommunikationsmodul. Die Komponenten können, müssen aber nicht, auf physisch verschiedenen Servern laufen. Weiterhin können die Komponenten bzw. Module redundant ausgelegt sein, sodass bei Ausfall einer oder mehrerer Komponenten (oder Module) ein transparentes „Fail-over” möglich ist.
-
Z. B. im Anwendungsbereich der Energiesteuerung in Energieversorgungsnetzen werden hohe Anforderungen an die Zuverlässigkeit gestellt, welche durch Redundanz erreicht werden sollen. Mindestens wird eine Redundanz im Sinne von zwei unabhängigen Steuersystemen wird verlangt, wobei nur der Ausfall eines kompletten Systems betrachtet wird. Wir betrachten die (verteilte) Redundanz jeder einzelnen Komponente des Gesamtsystems mit sich daraus ergebender Konfigurierbarkeit und Skalierbarkeit.
-
Dabei sollte auch eine gestörte Netzwerkverbindung zwischen den Modulen transparent berücksichtigt werden.
-
Auf TCP/IP basierende Lösungen lassen zwei Probleme außer Acht:
- – Bei TCT/IP wird davon ausgegangen, dass die Netzwerkverbindung entweder störungsfrei (mit den üblichen Mechanismen von TCP/IP) läuft oder aber abgebrochen ist. Insofern wird von verbindungsorientierter Kommunikation gesprochen. Durch TCP/IP-Mechanismen wird dafür gesorgt, dass die Auslieferung von gesendeten Daten garantiert wird, soweit die Verbindung noch besteht.
Der TCP/IP-Mechanismus in der bekannten Form erlaubt es aber nicht, mit kurzer Verzögerung automatisch zu entdecken, dass der Kommunikationspartner nicht mehr erreichbar ist (entweder wegen Netzwerkstörungen oder weil der andere Prozess nicht mehr verfügbar ist).
- – Da von dem Normalzustand ausgegangen wird (also bestehende Verbindung), wird der Fall des Verbindungsabbruchs nicht automatisch abgedeckt. Nach einem Verbindungsabbruch muss der Applikationslayer aktiv erneut eine Verbindung aufbauen.
Gerade in weniger stabilen Netzwerken (z. B. in Ländern mit schlechter Infrastruktur) besteht häufig ein „fluktuierendes” Netzwerk – manchmal ist das Senden eines Paketes möglich, zweitweise aber nicht, kurz danach wieder.
-
Weiterhin ist im Stand der Technik normalerweise jede Komponente fest mit einer bestimmten Aufgabe befasst, Skalierbarkeit lässt sich allenfalls statisch darstellen, indem leistungsfähigere Systeme benutzt werden oder indem bestenfalls auch mehrere Instanzen einer Komponente aufgebaut werden.
-
EP 2 938 004 A1 betrifft ein Verfahren gemäß dem Oberbegriff von Anspruch 1.
-
DE 10 2007 022 066 A1 betrifft ein Verfahren zur Überwachung eines GTP-Kommunikationspfades in einem UMTS/GPRS-Netzwerk, bei welchem Mittel zur Generierung einer GTP-C-Nachricht in Form von GTP-C-Echo-Request-Nachricht vorgesehen sind.
-
Aufgabe der vorliegenden Erfindung ist es, ein Verfahren zur Kommunikation zwischen Komponenten in einem Netzwerk bereitzustellen, welches in einem störungsanfälligen Netzwerk besser funktionieren kann.
-
Diese Aufgabe wird durch das Verfahren gemäß Anspruch 1 bzw. 2 gelöst. Weitere Ausgestaltungen der Erfindung sind in den abhängigen Ansprüchen definiert.
-
Die Erfindung wird anhand der Zeichnung näher erläutert. Dort zeigt
-
1 ein Beispiel mit drei Komponenten A, B, C in jeweils zwei redundanten Instanzen A1, A2; B1, B2; C1, C2; und
-
2 verschiedene Bewertungen.
-
Wie in 1 am Beispiel der Control-Unit gezeigt ist, kann jede Komponente einfach oder mit beliebiger Redundanz (z. B. einfacher Redundanz) vorhanden sein. Üblich ist 2, also einfache Redundanz, aber mehrere Instanzen lassen sich durch das vorgeschlagene Protokoll ebenso realisieren. Hier im Beispiel ist jede Komponente A B bzw. C jeweils in zwei redundanten Instanzen A1, A2; B1, B2 sowie C1, C2 vorhanden.
-
Eine Komponente hat jeweils eine Verbindung zu benachbarten Komponenten, mit welchen sie Daten austauschen muss (in 1 sind dies A mit B und A mit C; B mit A und C mit A. Allerdings müssen diese Verbindungen nicht dauerhaft bestehen. Diese Verbindungen sind als horizontale Pfeile dargestellt.
-
Statt jeweils eine Client-Server-Verbindung aufzubauen wie etwa im Stand der Technik bei TCP/IP, versendet erfindungsgemäß jede Komponente zur Kommunikation mit benachbarten Komponenten einfach UDP-(User Datagramm-Protokoll-)Pakete.
-
UDP-Kommunikation verzichtet auf eingebaute Mechanismen zur Ausliefergarantie für versendete Pakete und auch auf das Bestehen einer Verbindung. Die Datenpakete werden also ohne Rücksicht auf tatsächliches Vorhandsein der Verbindung und der Gegenstelle versendet. Beide Seiten einer Verbindung kennen die Adresse der Gegenstelle und senden ihre laufend mit Sequenznummer nummerierten Pakete dorthin.
-
Im Gegensatz zu TCP, welches „streamorientiert” arbeitet, ist UDP paketorientiert. Über TCP werden Daten in vom Protokoll bestimmten – dynamisch von den Umständen abhängigen – Paketen mit variabler Größe versendet. Dadurch kann der Datendurchsatz optimiert werden, es wird aber nicht garantiert, dass nach einem Empfangsvorgang auch der komplette gesendete Datensatz (also alle Datenpakete) empfangen wurde. UDP versendet komplette Pakete, so genannte Datagramme, als eine Einheit. Allerdings garantiert UDP nicht, dass Datagramme auch wirklich ausgeliefert werden. Wenn sie aber ausgeliefert werden, ist garantiert, dass das gesamte Datagramm ausgeliefert wird. Naturgemäß ergibt sich hieraus eine Größenbeschränkung für den zu übertragenden Datensatz, die aber in einem Bereich liegt, welcher für das vorliegende Verfahren völlig ausreichend ist.
-
Jedes empfangene Paket wird vom Empfänger durch ein UDP-Paket mit der entsprechenden Sequenznummer quittiert, welches an den Absender des empfangenen Pakets zurückgeschickt wird. Zusätzlich enthalten die Pakete noch eine Angabe über den eigenen Zustand des Senders.
-
Diese Kommunikation wird je Komponente jetzt gleichzeitig an mehrere Instanzen der Gegenseite durchgeführt. Durch die Ermittlung der Antwortzeiten und Betrachtung des übermittelten Zustandes kann eine Aussage über die Qualität der jeweiligen Instanz samt der Verbindung getroffen werden.
-
Die redundanten Instanzen einer Komponente stehen miteinander über denselben Mechanismus in Verbindung und tauschen jeweils Teile oder ihr komplettes Prozessabbild aus – synchronisieren sich also. Dabei kann festgelegt werden, dass eine Instanz als „Master” läuft und nur diese die Berechnungen ausführt, oder aber die Berechnungen parallel in allen Instanzen ausgeführt werden. Im ersten Fall wird eine Nicht-Master-Instanz erst dann anfangen, eigene Berechnungen weiter zu führen, wenn sie keine Verbindung zum Master findet.
-
Um das Vorhandsein des Gegenübers auch dann feststellen zu können, wenn keine neuen Daten auszutauschen sind, wird jede Instanz zu jedem Kommunikationspartner nach festgelegten Zeitintervallen ohne Aktivität ein „Ping”-Datagramm senden, auf das der Kommunikationspartner dann entsprechend wie auf Datenpakete antworten wird. ein Ping-Datagramm ist ein Datagramm ohne Nutzinformation (payload). Bei Ausbleiben der Antwort schaltet die sendende Instanz transparent auf die nächstbeste Instanz um. Es werden aber weiterhin alle Datagramme gesendet – also auch an die ausgefallene Instanz-, d. h. sobald die Verbindung/der Prozess wieder erreichbar ist, ist der vorherige Zustand wieder gegeben („ESTABLISHED”), ohne dass es weiteren Aufwandes bedarf.
-
In die Bemessung des eigenen Zustandes können u. a. Faktoren wie Prozessorlast o. ä., aber auch die Zuverlässigkeit der von den eigenen Kommunikationspartnern empfangenen Daten eingehen. Wenn eine Komponente beispielsweise nur von einer Instanz einer anderen Komponente empfangen kann, weil die Verbindung zu der anderen Instanz dieser Komponente ausgefallen ist, kann der Zustand herabgesetzt werden. Ebenso, wenn die von zwei Instanzen empfangen Daten beispielweise nicht konsistent sind.
-
Durch geschickte Anordnung der Komponenten in einem Netzwerk lässt sich eine hohe Zuverlässigkeit mit relativ geringem Aufwand und mit echtem Fail-Over erreichen.
-
Skalierbarkeit folgt dem erfindungsgemäßen Verfahren direkt. Da eine beliebige Anzahl von Instanzen je Komponente instanziiert werden kann, kann damit auch eine dynamische Verteilung der Arbeitslast einer Komponente erreicht werden. Es werden vervielfachte Instanzen nicht nur zur Erreichung von Redundanz verwendet, sondern auch zur Aufteilung der Aufgabe der Komponente (beispielweise Überwachung einer großen Zahl von Anlagen). Durch die laufende Überwachung des Zustandes der einzelnen Instanzen kann auf sich verschlechternden Zustand (z. B. durch zu hohe Last) reagiert werden, indem weitere Instanzen gestartet werden, die Teile der Last übernehmen.
-
Durch das erfindungsgemäße Verfahren ergibt sich die Skalierbarkeit, indem die Instanzen nicht an einen konkreten Host gebunden sind sondern auf beliebige Hosts verteilt werden können.
-
Zunächst soll die Kommunikation und die Synchronisation zwischen zwei Partnern im Einzelnen betrachtet werden.
-
A und B seien zwei Komponenten in unserem Energiesystem, beispielweise zentrale Steuerung (Control-Unit) und Kommunikationskomponente, vgl. 1.
-
Zunächst betrachten wir die Kommunikation und Synchronisation zwischen jeweils einer Instanz von A und B (A1 und B1).
-
Beide Komponenten werden über eine initiale Konfiguration so aufgebaut, dass sie die IP-Adresse und den Port des Gegenparts, mit dem sie zu kommunizieren bestimmt sind, kennen. Sie öffnen dann jeweils einen Socket, über den UDP-Datagramme zum Gegenpart versendet werden können. Beide Komponenten starten jetzt unabhängig mit der Kommunikation; sofern Daten an die Gegenseite zu übertragen sind, werden diese wie weiter unten spezifiziert gesendet. Jedes UDP-Paket (Datagramm) ist hierbei wie folgt aufgebaut (vgl. auch Tabelle 1):
Ein UDP-Paket enthält immer die Angabe der Datenquelle (z. B. zentrale Steuerung, Energieerzeugungsanlage usw.), wobei diese über das Gesamtsystem eindeutig identifiziert sein muss (z. B. durch eine Nummer aus einem Nummernraum für die verschiedenen Komponententypen, aber eine andere eindeutige Aufzählung ist ebenso denkbar, solange eben die Eindeutigkeit gewährleistet ist).
-
Weiterhin enthält jedes UDP-Paket eine für die Kombination Sender-Empfänger fortlaufende Sequenznummer.
-
Drittens ist im UDP-Paket ein Datagrammtyp enthalten, der die Art des übertragenen Nutzinhaltes angibt und somit eine Dekodierung desselben auf der Gegenseite ermöglicht.
-
Viertens im UDP-Paket enthalten ist die Senderichtung (Anfrage oder Bestätigung (Quittung)). Ein von einer Seite initiiertes Datagramm enthält die Senderichtung „Anfrage”, direkt nach Empfang wird vom Empfänger ein entsprechendes Datagramm mit Senderichtung „Bestätigung” zurück gesendet.
-
Fünftens im UDP-Paket enthalten ist ein Zeitstempel, der zum Abgleich der Paketlaufzeiten verwendet werden kann. Der Zeitstempel ist immer der Zeitpunkt der Absendung des Datagramms.
-
Des Weiteren im UDP-Paket sind weitere Daten, der eigentliche Nutzinhalt des Paketes enthalten, je nach Typ des Datagramms variierend.
Feld | Format |
Originator | Integer |
SequenceNo | Integer |
TelegramType | Byte |
Senderichtung | REQUEST/RESPONSE |
Timestamp | DateTime |
Payload | Byte Array |
Tabelle 1: Allgemeine Datagrammstruktur
-
Bei Empfang eines Datagramms von der Gegenseite sendet jede Komponente sofort eine Quittung zurück.
-
Je nach erhaltener Quittung bewertet jede Komponente je Gegenseite den Zustand der Kommunikationsverbindung zwischen der Komponente und der jeweiligen Gegenseite. Folgende Zustände sind möglich:
- – UNKNOWN → es kann noch keine Aussage über die Gegenseite getroffen werden,
- – ESTABLISHED → eine Antwort der Gegenseite ist innerhalb des vorgegebenen Zeitfensters eingetroffen
- – FAILED → innerhalb des einfachen Zeitfensters ist keine Antwort eingetroffen
-
Nach dem Start einer Komponente wird zur Gegenseite ein „Ping”-Datagramm gesendet, d. h. ein Datagramm mit leerem Payload, um die Gegenseite zum Senden einer Quittung aufzufordern.
-
Wenn eine Quittung oder eine anderes Datagramm (je nach Quittierungsverfahren, s. u.) empfangen wurde, gilt die Verbindung als aufgebaut (ESTABLISHED).
-
Wenn während eine Periode Tping/2 keine Quittung empfangen wurde, wird ab jetzt alle Tping/2 ein erneutes Ping-Datagramm gesendet. Wenn nach Ablauf von Tping keine Quittung empfangen wurde, wird der Zustand FAILED gesetzt.
-
Die Periode Tping ist einerseits klein genug zu wählen, um die Anforderungen der Applikation auf schnelle Reaktion auf Ausfall zu gewährleisten, andererseits groß genug, um genügend Zeit für Senden eines Requests und Empfangen einer Response über das jeweilige Netzwerk zu gewährleisten und außerdem das Netz nicht mit unnötigen Paketen zu fluten. Typischerweise ist ein Wert von 4–5 Sekunden geeignet.
-
Im normalen weiteren Ablauf können dann in unregelmäßigen Zeitabständen Datagramme versendet und jeweils vom Empfänger sofort quittiert werden.
-
Tabelle 2 zeigt eine typische Abfolge von Datagrammen, wobei Komponente A zum Zeitpunkt 0 bereits seit einiger Zeit gestartet war, Komponente B startet aber erst zum Zeitpunkt 3; ta ist die Datagramm-Laufzeit von Komponente A zu B, tb umgekehrt – das Zeitfenster Tping zum Empfangen einer gültigen Nachricht sei 4 Sekunden.
-
Zum Zeitpunkt t = 0 sei Komponente A also bereits seit einiger Zeit gestartet und habe demnach bereits 9-Ping Datagramme (Ping Request 1 bis 9, nicht gezeigt) an Komponente B gesendet, die jedoch unbeantwortet geblieben sind, da B noch nicht gestartet war.
Zeitpunkt [s] | Komponente A | Zustand von Verbindung zu B, ermittelt durch A | Komponente B | Zustand von Verbindung zu A, ermitelt durch B |
0 | Send Ping Request 10 | FAIL | - | |
2 | Send Ping Request 11 | FAIL | - | |
3 | | FAIL | Send Ping Request 1 | UNKNOWN |
3 + tb | Send Ping Response 1 | ESTABLISHED | | |
3 + ta | Send Ping Request 12 | | | |
3 + ta + tb | | | Receive Ping Response 1 | ESTABLISHED |
3 + 2·ta + tb | | | Send Ping Response 12 | |
3 + 2·ta + 2·tb | Receive Ping Response 12 | ESTABLISHED | | |
5 | Send Value Request 13 | | | |
5 + ta | | | Send Value Response 13 | |
8 | Send Ping Request 14 | | Send Ping Request 2 | |
8 + ta/tb | Send Ping Response 2 | | Send Ping Response 14 | |
10 | usw. | | | |
| | | | |
30 | Send Ping Request 20 | ESTABLISHED | No reaction | |
32 | Send Ping Request 21 | ESTABLISHED | No reaction | |
34 | B timed out | FAILED | | |
34 | Send Ping Request 22 | | | |
36 | Usw. | | | |
44 | Send Ping Request 27 | FAILED | B now re-established | |
44 + ta | | | Send Ping Response 27 | |
44 + ta + tb | Receive Ping Response 27 | ESTABLISHED | | |
| usw. ... | | | |
Tabelle 2: Verlauf einer Kommunikation zwischen zwei Komponenten A und B
-
Je nach Anforderung an Verlässlichkeit können zwei verschiedene Methoden zur Feststellung des Verbindungsabbruchs zwischen zwei Komponenten A, B verwendet werden:
- 1. Sobald (irgend) ein Datagramm von der Gegenseite empfangen wird, wird in der bewertenden Komponente A bzw. B eine interne Uhr (Zeitstempel), von der aus Tping /2 und Tping gerechnet werden, zurück gesetzt auf Null.
- 2. Die interne Uhr (Zeitstempel) wird jeweils auf den Zeitpunkt gesetzt, der dem Sendezeitpunkt eines Telegrams entspricht, zu welchem eine Quittung empfangen wurde; bei Empfang eines „Request”-Datagramms wird die Uhr auf den Sendezeitpunkt des Datagramms gesetzt.
-
Methode 1 ist wesentlich einfacher zu implementieren, dafür aber weniger genau; es können durchaus Datagramme empfangen werden, die länger unterwegs waren, während der Gegenpart zum aktuellen Zeitpunkt eigentlich gar nicht mehr existiert. Im Beispiel der Tabelle 1 ist diese Methode zugrunde gelegt. 2 zeigt, wie der Methode 1 die Bewertungen geändert werden, je nachdem, ob ein Datagramm erhalten wurde oder nicht.
-
Methode 2 erfordert dagegen in der bewertenden Komponente eine interne ”Buchführung” über die versendeten Datagramme, d. h. alle gesendeten Datagramme müssen in einer Liste vorgehalten werden, bis sie quittiert wurden.
-
Wann immer eine Quittung für ein Datagramm empfangen wird (identifiziert durch Sequenznummer), kann dieses und alle älteren Datagramme aus der Liste entfernt werden.
-
Bei Empfang eines Request-Datagramms können alle Datagramme aus der Liste entfernt werden, die älter als der Sendezeitpunkt des empfangenen sind.
-
Zur Einführung von Redundanz können durch das oben beschriebene Verfahren gleichermaßen mehrere (gewöhnlich zwei) Instanzen jeder Komponente miteinander kommunizieren. Dafür werden erfindungsgemäß wir zwei verschiedene Alternativen der Datensynchronisation vorgeschlagen:
- 1. Jede Instanz versorgt sich mit den benötigten Eingabedaten von ihren konfigurierten Kommunikationspartnern (nach dem oben beschriebenen Verfahren) und führt völlig autonom eigene Berechnungen unabhängig von den anderen Instanzen durch.
- 2. Eine der Instanzen wird von Beginn an als „Master” designiert. Diese sendet ihr Prozessabbild, d. h. all relevanten Daten, an die anderen Instanzen. Erst im Falle, dass eine Instanz vom „Master” keine Daten mehr erhält (Zustand → FAILED), wird sie die Berechnungen eigenständig weiterführen. Dies ist in 1 gezeigt; dort sind die oberen Komponenten A1, B1, C1 die Master-Instanzen, die ihre Daten mit den unteren Slave-Instanzen A2, B2, C2 synchronisieren (senkrechte Pfeile). Wenn eine Verbindung (horizontaler Pfeil) mit der jeweiligen Master-Instanz ausfällt, springt die jeweilige Slave-Instanz ein und übernimmt die Kommunikation (schräger Pfeil).
-
Alternative 1 ist robuster und leichter zu implementieren, wird jedoch möglicherweise in der Praxis zu geringen Abweichungen zwischen den Instanzen führen (z. B. wegen Timing etc.).
-
Alternative 2 erfordert größeren Aufwand für die Datensynchronisation, stellt jedoch sicher, dass mehrere Instanzen die Daten völlig synchron halten.
-
Für jede Verbindung zu einer anderen Komponente kann nun ausgewählt werden, von welcher Instanz die Daten bezogen werden. Im einfachsten Fall der Implementierung wird die Instanz verwendet, die den besten Zustand (s. oben) besitzt.
-
Indem auch zu ausgefallenen Instanzen weiter Ping-Datagramme geschickt werden, kann sehr schnell erkannt werden, wenn die Instanz wieder funktioniert. Damit ist dann ein „Rückschwenken” leicht.
-
Zusätzlich zu dem o. g. Mechanismus zur Erkennung von Abbrüchen kann jede Instanz einer Komponente in jedem Datagramm ihren eigenen Zustand („Health”) übermitteln. Dieser ist Sache einer lokalen Implementierung, kann aber z. B. eine Funktion der Prozessorlast sowie des Zustandes der versorgenden Komponenten sein.
-
Dieser übermittelte Zustands-Wert kann zusätzlich in die Beurteilung eingehen, welche Instanz einer versorgenden Komponente aktiv verwendet wird, ebenso wie die Laufzeit eines Datagramms bis zum Empfang der Quittung.
-
Hier ist je nach Anforderung der Anwendung eine geeignete Funktion zu verwenden.
-
O. g. Verfahren ermöglicht es ebenfalls, mehrere Instanzen einer Komponente zu starten um Skalierbarkeit zu erreichen.
-
Dieses lässt sich wiederum in zwei Aspekte aufteilen:
- 1. Dynamisch Skalierbarkeit. Eine zentrale Komponente unterhält Verbindungen zu allen anderen Komponenten und überwacht die Verfügbarkeit und die Gesundheit der Instanzen wie oben. Wenn einzelne Instanzen nicht erreichbar sind oder die Gesundheit sich unter eine vorgegebenen Wert verschlechtert, können automatisch weitere Instanzen gestartet werden. Dazu müssen allen beteiligten Komponenten von vorneherein die Kommunikationsparameter aller erzeugbaren Instanzen parametriert werden.
- 2. Statische Skalierbarkeit. Eine Komponente kann in mehrere Instanzen aufgeteilt werden, die jeweils einen Teilbereich der Aufgabe der Komponente abdecken. Dieses bietet sich z. B. bei Kommunikationskomponenten zu Energieanlagen-Steuerungen an, die erfahrungsgemäß nur eine begrenzte Anzahl Anlagen bedienen können. Um mehr Anlagen anschließen zu können, werden nun einfach nicht-überlappende Instanzen der Komponente erzeugt.
-
Die vorliegende Erfindung umfasst auch Programmcode, der, wenn in eine Datenverarbeitungsvorrichtung geladen, diese so steuert, dass sie das erfindungsgemäße Verfahren ausführt.
-
Ebenfalls umfasst die Erfindung Datenträger und/oder Signalfolgen, welche den zuvor genannten Programmcode enthalten.
-
Ferner umfasst die Erfindung eine Komponente, welche ausgestaltet ist, das erfindungsgemäße Verfahren auszuführen.