Routing

Zum Versenden von Nachrichten genügt es, eine Empfängeradresse in dem Envelope zu setzen. Anschließend wird die Nachricht einer Sendemethode übergeben, und die Nachricht wird zugestellt. Doch wie findet das System das richtige Target auf einem anderen Host irgendwo im Netzwerk? Das Framework muss für diese Aufgabe jeden Host im Netzwerk ermitteln können. Da es kein zentrales Verzeichnis aller Rechner bzw. D1-Instanzen im Netz gibt, muss es einen anderen Mechanismus geben.

Für das Routing benötigen wir alle Verbindungen zwischen den D1-Instanzen in einem Netzwerk. Wenn ein Host C mit einem Host D verbunden wird, entsteht eine neue Teilstrecke CD. Beide Hosts kennen nun einander.

Wenn nun C aber schon mit den Hosts A und B, und der Host D schon mit den Hosts E und F verbunden war, entsteht ein größeres Netzwerk:

A--\         /--E          A--\     /--E
    C   +   D       =          C---D
B--/         \--F          B--/     \--F

Die neue Verbindung C–D muss den anderen Hosts (ABEF) mitgeteilt werden. Aber das genügt nicht, den A und B kennen noch nicht die Verbindungen DE und DF. Und Die Hosts E und F wissen nichts über die Verbindungen AC und BC.

Ein spezieller Flooding-Broadcast sorgt hier für eine schnelle und bandbreitenschonende Information für alle Hosts, ohne dass das die Gesamtheit aller Verbindungen an alle Hosts geschickt werden muss.

Ähnlich verhält es sich bei einem Verbindungsbruch. Wird die Verbindung CD unterbrochen, merken es zunächst die Hosts C und D. Aber C verliert dann nicht nur D, sondern auch E und F. Ähnliches gilt für alle anderen Hosts. Dennoch muss nur die Unterbrechung von C und D an die Hosts gemeldet werden.

Jeder Host hat eine Liste von allen Verbindungen im Netzwerk (hier AC, BC, CD, DE, DF). Mit diesem Netz an Graphen kann man über den Djikstra-Algorithmus jederzeit die schnellste Route durch ein Netz finden, z.B. von A nach F. Dieses gilt auch, wenn mehrere Wege zum Ziel führen. Der Algorithmus entdeckt auch nicht erreichbare Hosts, also Hosts, die von einem Ausgangspunkt nicht erreicht werden können. Wird die Verbindung CD unterbrochen, kann F nicht mehr von A erreicht werden.

Um die Strecken zwischen den einzelnen Hosts zu bewerten, senden die Hosts Ping-Nachrichten zu den benachbarten Hosts. Dadurch ist bekannt, wie schnell eine Nachricht zwischen den Hosts versandt werden kann. Der Routing-Algorithmus findet so die schnellste Route einer Nachricht durch das Netz.

Jede D1-Instanz hat ein aktuelles Graphennetz und kann das Routing für eine Nachricht komplett errechnen. Interessieren würde uns aber nur der nächste Schritt, also der nächste Host, an den eine Nachricht weiter vermittelt werden müsste. Dieser nächste Host wird dann den übernächsten Host bestimmen usw. Das führt zu dem Kuriosum, dass eine Nachricht, die schon unterwegs ist, bei einem Verbindungsabbruch in einer Strecke vor ihr die Richtung ändern kann, wenn eine Alternativstrecke existiert. Ansonsten würde sie mit einem Fehlercode zurückgeschickt werden.

Wichtig

Diese Routing-Mechanismen ermöglichen es uns, Nachrichten über ein Netz zu einer anderen D1-Instanz zu schicken, ohne dass der Programmierer wissen muss, welche Verbindungen aktuell intakt sind, und ohne dass eine Direktverbindung zum Ziel existieren muss. Das ist eine neue Herangehensweise an Distributed Objects, an verteilte Programme, an Message Passing. Sie ermöglicht uns, Objekte über ein Netzwerk zu verteilen, und diese Verteilung jederzeit zu ändern. Und das, ohne einen zentralen Server oder eine Middleware zu benutzen.

Hinweis

Zur Zeit gelingt es uns, die Verteilung der Objekte in der Konfiguration zu dokumentieren. Ein Objekt kann der Konfiguration entnehmen, welche Adresse der Zielservice zur Zeit besitzt. In eine der nächsten D1-Varianten werden wir eine verteilte Service-Registry einführen, die diese Aufgabe übernimmt. Dann können Services sich bei ihr anmelden, und die Stakeholder des Services müssen nicht einmal diese Adresse kennen.