266 lines
25 KiB
Markdown
266 lines
25 KiB
Markdown
# Millionen langlebiger TCP-Verbindungen – Herausforderungen und Lösungen bei Update-Prozessen
|
||
|
||
Ihr wollt in euren Urlaub starten, seid mit gepackten Koffern am Bahnhof. Beim Warten auf den verspäteten Zug habt ihr jede
|
||
Menge Zeit zum überlegen. Ihr fragt euch: "Ist der Herd wirklich abgeschaltet?". Anders als in früheren Urlauben habt ihr aber
|
||
einen smarten Herd daheim. Ihr öffnet eure App, stellt fest, dass alles in Ordnung ist, und könnt beruhigt in Urlaub starten.
|
||
|
||
IoT (also "Internet of Things") beschreibt genau diese Art von Geräten. Mein Name ist Bene. Ich bin Softwareentwickler mit Fokus
|
||
auf Softwarearchitektur bei Scandio. Wir bei Scandio entwickeln für unsere Kunden maßgeschneiderte intelligente und kreative
|
||
Softwarelösungen. Wir haben dabei einen Schwerpunkt unter anderem im Bereich "Internet of Things".
|
||
|
||
Ein Projekt aus diesem Bereich will ich heute vorstellen. Dabei geht es darum, wie die IoT-Geräte unseres Kunden mit
|
||
verschiedenen Backends kommunizieren und um die Herausforderungen bei der Aktualisierung des Systems, das zwischen den Geräten
|
||
und den Backends liegt.
|
||
|
||
## Inhalt
|
||
|
||
Ein kurzer Überblick über den Vortrag: Nach dem Projektsetup (also Hintergrund, Motivation und Ziel des Projekts) beschreibe ich
|
||
euch die Problemstellung etwas genauer und dann natürlich auch die Lösungen, also: wie sieht die Architektur des Systems jetzt
|
||
aus, was genau passiert, wenn das System Updates bekommt, und zum Schluss noch: was wären unsere Wunschträume für die
|
||
Architektur, wenn Zeit und Geld keine Rolle spielen würde oder wir ganz von vorne anfangen würden.
|
||
|
||
Eine organisatorische Bemerkung: wenn während des Vortrags Fragen aufkommen, stellt sie gerne sofort und ich werde sie so gut
|
||
wie möglich beantworten.
|
||
|
||
## Über Scandio
|
||
|
||
Noch kurz ein paar Worte über Scandio: Vorhin habe ich ja schon gesagt, dass wir individuelle Software entwickeln, wobei wir
|
||
neben IoT noch Stärken in den Bereichen Cloud und Systems Engineering, DevOps und Fullstack-Web-Entwicklung haben. Daneben
|
||
unterstützen wir mit agilen Coaches und Beratern dabei, Prozesse zu optimieren. Insbesondere helfen wir als Atlassian Platinum
|
||
Solution Partner unseren Kunden bei ihrer agilen Transformation.
|
||
|
||
## Projektsetup
|
||
|
||
[5] Das Projekt, von dem ich heute rede, hat den Namen "Heimdall".
|
||
|
||
Heimdall ist in der nordischen Mythologie der Wächter der Götterbrücke Bifröst (das ist der Regenbogen im Bild) und Heimdall hat
|
||
außergewöhnliche Wahrnehmungsfähigkeiten. Hier im Bild ist das durch das Hören symbolisiert. Genauso wie Heimdall die Verbindung
|
||
zwischen den Welten überwacht, fungiert unser Heimdall-System als ein Gateway, das die Brücke zwischen einer Vielzahl von
|
||
IoT-Geräten und verschiedenen Backend-Systemen bildet. Ähnlich der mythischen Figur hat unser Heimdall die Aufgabe, die
|
||
Sicherheit, Stabilität und Effizienz dieser Verbindungen zu gewährleisten.
|
||
|
||
Heimdall wird seit 2018 entwickelt und hat ein vollständig extern entwickeltes und verwaltetes System abgelöst. Bei diesem alten
|
||
System hatte unser Kunde keinen Zugriff auf den Source Code oder Entwicklungsdetails. Daher wurde die Entscheidung für eine
|
||
Neuentwicklung getroffen. Die fehlenden Informationen über das alte System gingen sogar so weit, dass wir bei der Migration zu
|
||
unserem neuen System regelmäßig das alte System überlastet haben, da wir einfach keine Informationen bekommen konnten, welche
|
||
Last das alte System aushält. Mit diesem Lock-In-Effekt war unser Kunde verständlicherweise unzufrieden und hat uns beauftragt,
|
||
Heimdall neu zu entwickeln.
|
||
|
||
Ich will hier einmal schematisch zeigen, welche Aufgabe Heimdall hat. Eure smarte Herdplatte von vorhin muss regelmäßig an das
|
||
Herdplattenstatusbackend die Information senden, welche Herdplatten auf welcher Stufe angeschaltet sind. Gleichzeitig tauscht
|
||
das smarte Heizungsthermostat eures Nachbarn Nachrichten mit einem Backend aus, um herauszufinden, ob die Heizung nach oben oder
|
||
unten geregelt werden sollte, und die smarte Dunstabzugshaube eurer Tante meldet an das entsprechende Backend, dass die Filter
|
||
mal wieder eine Reinigung bräuchten. Heimdall sitzt zwischen den Geräten und den Backends und sorgt dafür, dass die richtigen
|
||
Nachrichten das richtige Backend erreichen, und dass umgekehrt auch Nachrichten in die Gegenrichtung versendet werden können:
|
||
beispielsweise kann das Herdplattenbackend die Herdplatte anweisen, sich abzuschalten. Die Geräte halten dazu eine Verbindung zu
|
||
Heimdall aufrecht. Über diese Verbindung werden die Nachrichten dann ausgetauscht.
|
||
|
||
## Problemstellung
|
||
|
||
[10] Das wichtigste Qualitätsziel bei Heimdall ist, dass diese Verbindungen zwischen Gerät und Heimdall so selten wie möglich
|
||
unterbrochen werden. Das hat zwei Gründe: Zum einen kann ich als Nutzer nicht sehen, auf welcher Stufe mein Herd gerade kocht,
|
||
wenn der Herd nicht mit Heimdall verbunden ist. Zum anderen finden einige Prozesse nach jeder Neuverbindung statt. Das kann
|
||
potenziell zu Überlastung von Heimdall oder den Backends führen, wenn die Neuverbindungen zu häufig stattfinden.
|
||
|
||
Ein Szenario gibt es aber, in dem Verbindungen auf keinen Fall gehalten werden können: nämlich wenn der Server, mit dem die
|
||
Hausgeräte verbunden sind, ein Update bekommt und daher ersetzt werden muss. Deswegen ist eins der größten Ziele bei der
|
||
Entwicklung der Architektur von Heimdall, dass solche Neustarts bei den meisten Konfigurationsänderungen des Systems nicht
|
||
notwendig sind, sondern die Konfigurationsänderungen am Live-System durchgeführt werden können.
|
||
|
||
## Lösungen
|
||
|
||
Diesem Prinzip, dass Konfigurationsänderungen ohne Neustarts möglich sein sollen, werden wir bei der Betrachtung der
|
||
Heimdall-Architektur noch öfter begegnen. Wir schauen uns jetzt mal an, wie Heimdall aufgebaut ist.
|
||
|
||
Das Kernstück von Heimdall ist der sogenannte "Web Socket Manager", kurz WSM. Eure Herdplatte kann über euer heimisches WLAN mit
|
||
Idem Internet kommunizieren. Nachdem die Firmware der Herdplatte gestartet und die Verbindung mit dem Internet hergestellt
|
||
wurde, versucht die Herdplatte eine Websocket-Verbindung zum WSM zu öffnen. Dabei handelt es sich um eine dauerhafte Verbindung,
|
||
über die zu beliebigen Zeiten Nachrichten in beide Richtungen entlang der Verbindung geschickt werden können. Die Verbindung
|
||
wird so lange wie möglich aufrecht erhalten. Es gibt im Wesentlichen vier Gründe für den Abbruch der Verbindung: Das Gerät wurde
|
||
abgeschaltet, die Netzwerkverbindung zwischen Gerät und WSM wurde unterbrochen, der WSM wurde beendet oder der WSM hat die
|
||
Verbindung beendet. Im letzten Fall teilt also der WSM dem Gerät mit, dass über die Verbindung keine Daten mehr entgegengenommen
|
||
oder verschickt werden können, ohne dass WSM oder Gerät beendet wurden. Gehen wir also mal davon aus, dass die Verbindung
|
||
geöffnet ist und die Herdplatte mit dem WSM kommuniziert. Dann leitet der WSM die Nachrichten des Geräts an ein Backend weiter
|
||
und umgekehrt werden Nachrichten vom Backend an das Gerät zurückgeleitet. Wenn es nur ein Gerät und nur ein Backend geben würde,
|
||
wäre ich jetzt fertig mit der Präsentation. Das ist aber natürlich nicht alles.
|
||
|
||
[15] In Wirklichkeit gibt es ja außer eurer Herdplatte auch noch den Thermostat eures Nachbarn, die Dunstabzugshaube eurer Tante
|
||
und noch jede Menge andere Geräte, die mit den Backend-Systemen kommunizieren sollen. Unser Deployment ist in vier verschiedene
|
||
Regionen aufgeteilt, und in der größten Region, der Region Europa, haben wir aktuell etwa 2,5 Millionen Geräte, die zur gleichen
|
||
Zeit mit Heimdall verbunden sind. Deshalb gibt es auch mehrere WSM-Pods, also mehrere Instanzen des WSM. Zum einen wird dadurch
|
||
die Skalierbarkeit des Systems verbessert, und zum anderen verlieren im Falle eines Crashs nicht alle Geräte gleichzeitig die
|
||
Verbindung. Vor diesen Instanzen liegt ein Load Balancer, der versucht, die Verbindungslast möglichst gleichmäßig zu verteilen,
|
||
um Rechenressourcen möglichst effizient nutzen zu können. Der Load Balancer routet die Verbindungen von den Geräten zum WSM im
|
||
Round-Robin-Algorithmus, also: eure Herdplatte verbindet sich zuerst und wird an die erste Instanz geroutet, danach kommt die
|
||
smarte Glühbirne eures Freunds, die wird dann an die zweite Instanz geroutet, und nach der letzten Instanz beginnt das Spiel von
|
||
vorne. Bei synchronen Aufrufen an das Backend kommt die Antwort an die richtige WSM-Instanz zurück. Allerdings führen synchrone
|
||
Aufrufe zu zwei Nachteilen: zum einen muss der WSM auf die Antwort des Backends warten und so lange die Verbindung zum Backend
|
||
offen halten. Wenn sehr viele Nachrichten auf einmal verschickt werden und das Backend langsam arbeitet, kann das zur
|
||
Überlastung des WSM führen. Ein zweiter Nachteil von synchronen Aufrufen ist die stärkere Kopplung: die Verarbeitung der
|
||
Nachricht schlägt nämlich fehl, wenn das Backend oder weiter innen liegende Systeme bei der Verarbeitung der Nachricht
|
||
scheitern. Da sind asynchrone Aufrufe die bessere Lösung. Das heißt, dass entweder das Backend die Nachricht entgegennimmt und
|
||
erst im Nachgang verarbeitet, oder dass der WSM die Nachricht an einen hochverfügbaren Message Broker schickt und die Backends
|
||
die Nachricht in ihrer Geschwindigkeit zu einer späteren Zeit konsumieren können. Egal, für welche Lösung man sich hier
|
||
entscheidet: das Backend muss eine Nachricht zurück an das Gerät senden, weiß aber noch nicht, mit welcher WSM-Instanz das Gerät
|
||
verbunden ist. Übrigens hätten wir das selbe Problem auch ganz ohne asynchrone Aufrufe: sagen wir mal, euer Nachbar möchte seiner
|
||
Heizung mitteilen, dass sie die Temperatur in der Wohnung auf 22 Grad hochregeln soll, weil er jetzt auf dem Heimweg ist. Dann
|
||
muss das Heizungsbackend eine Nachricht an den Thermostat schicken. Wenn das Backend versucht, die Nachricht über eine zufällige
|
||
Instanz des WSM zu schicken, ist die Chance nicht sehr hoch, dass der Thermostat gerade mit dieser Instanz verbunden ist.
|
||
|
||
Hier kommen der Forwarding-Service (kurz FORS) und eine Adress-Datenbank ins Spiel. Jeder WSM-Pod schreibt nach einer geöffneten
|
||
Verbindung mit einem Gerät die Geräte-ID zusammen mit der eigenen Adresse in die Adress-Datenbank. Der FORS fragt jetzt für ein
|
||
Gerät die richtige Adresse ab und kann Nachrichten vom Backend an die richtige WSM-Instanz weiterleiten. Konkret schaut der
|
||
Ablauf also so aus: Gerät 1 baut eine Websocket-Verbindung zu WSM-Pod 1 auf. In der Folge teilt WSM-Pod 1 der Adress-Datenbank
|
||
mit: Gerät 1 ist mit dem Pod verbunden, der Adresse 1 besitzt. An der Kommunikation vom Gerät zum Backend hat sich nichts
|
||
geändert. Wenn jetzt aber das Backend eine Nachricht an das Gerät senden möchte, dann wird die Nachricht an unseren
|
||
Forwarding-Service geschickt. Der Forwarding-Service fragt die konkrete Adresse des richtigen WSM-Pods bei der Adress-Datenbank
|
||
an und leitet die Nachricht entsprechend weiter. Dann ist die Nachricht beim richtigen WSM gelandet und kann an das Gerät über
|
||
die Websocket-Verbindung geschickt werden.
|
||
|
||
[20] Dazu kommt, dass es in Wirklichkeit nicht nur ein Backend gibt. Ein Message Mapping kann vom WSM genutzt werden, um zu
|
||
entscheiden, an welches Backend ein konkreter Nachrichtentyp mit einer konkreten Version gesendet werden soll. Der Ablauf hier
|
||
ist also: Das Gerät (der Einfachheit halber habe ich in diesem Bild nur noch ein Gerät) schickt die Nachricht mit dem Typ
|
||
"/foo/config" und der Version 1 an den WSM. Der WSM findet mit Hilfe des Message Mappings heraus, dass Backend 1 für die
|
||
Verarbeitung der entsprechenden Nachrichten verantwortlich ist und leitet die Nachricht entsprechend weiter. Wir sind also wie
|
||
ein Postunternehmen dafür zuständig, dass die richtigen Nachrichten an den richtigen Empfänger gelangen, aber nicht dafür, dass
|
||
die Nachrichten inhaltlich auch sinnvoll sind. Es findet also bei Heimdall keinerlei Validierung der Nachrichten statt. Das
|
||
Message Mapping ändert sich regelmäßig. Deshalb ist es wichtig, dass eine Rekonfiguration ohne Neustart der WSM-Pods möglich
|
||
ist, da sonst ja Verbindungen gekappt werden müssten.
|
||
|
||
Der WSM hat noch diverse andere Aufgaben:
|
||
|
||
* Er führt den TLS-Handshake durch. Das heißt: alle Informationen, die zwischen Gerät und WSM ausgetauscht werden, werden
|
||
verschlüsselt ausgetauscht. Dabei muss sich sowohl der Server, also der WSM, beim Gerät authentifizieren, als auch das Gerät
|
||
nachweisen, dass es sich tatsächlich um ein Gerät unseres Kunden handelt. Die Authentifizierungen finden statt, indem
|
||
überprüft wird, dass Gerät und WSM beide Zertifikate besitzen, die von einer vertrauenswürdigen Entität, also einer
|
||
Certificate Authority (kurz CA) des Kunden signiert wurden.
|
||
* Bei der Validierung des Zertifikats, das das Gerät ausweist, gibt es noch ein paar Details zu beachten. Nämlich gibt es etwa
|
||
10 verschiedene ausstellende CAs, also Certificate Authorities, denen der WSM vertrauen soll. Manche dieser CAs haben
|
||
Zertifikate ausgestellt, die inzwischen abgelaufen sind und die daher von einer Standard-Validierung nicht akzeptiert werden
|
||
würden. Das Problem dabei: für Firmware-Updates müssen auch Nachrichten über Heimdall ausgetauscht werden, und die
|
||
entsprechenden Geräte-Zertifikate können ohne ein Firmware-Update nicht aktualisiert werden. Deshalb muss Heimdall auf die
|
||
Validierung des Gültigkeitszeitraums für die entsprechenden CAs verzichten.
|
||
* Manche Geräte-Zertifikate sollen außerdem sofort abgelehnt werden, weil die entsprechenden Geräte defekt sind. Das wird über
|
||
eine Datenbank mit blockierten Zertifikaten geregelt. Für das Blockieren eines Zertifikats ist wie beim Message Mapping kein
|
||
Neustart des WSM notwendig, sodass auch hier Neuverbindungen vermieden werden.
|
||
* Noch einmal andere Geräte sind in einem Quarantäne-Status. Für diese Geräte dürfen nur bestimmte Nachrichten versendet und
|
||
empfangen werden, beispielsweise wieder Nachrichten im Zusammenhang mit Firmware-Updates. Wie die blockierten Zertifikate wird
|
||
das über eine eigene Datenbank konfiguriert und benötigt keinen WSM-Neustart.
|
||
* Dann muss der WSM noch den Websocket-Upgrade durchführen (dazu sage ich später noch mehr).
|
||
* Schließlich gibt es noch einen Corporate Handshake, der vom Protokoll unseres Kunden vorgesehen ist. Bevor dieser Handshake
|
||
abgeschlossen ist, dürfen keine anderen Nachrichten in beide Richtungen gesendet oder weitergeleitet werden.
|
||
|
||
[25] Hier ist noch einmal eine Zusammenfassung des gesamten Heimdall-Systems, soweit es für den Vortrag relevant ist. Die
|
||
Grundidee ist also, dass der WSM so selten wie möglich neugestartet werden muss. Das erreichen wir, indem Konfiguration, die
|
||
sich regelmäßig ändern könnte, externalisiert wird und ohne Neustarts geändert werden kann. Das sieht man in diesem Bild durch
|
||
das Message Mapping und die beiden Datenbanken zum Blockieren von Zertifikaten und für den Quarantäne-Status.
|
||
|
||
Was passiert jetzt aber, wenn der WSM doch einmal neugestartet werden muss oder abstürzt? Wenn ein WSM-Pod kontrolliert beendet
|
||
wird, werden die Verbindungen zu den entsprechenden Geräten nacheinander beendet. Dann verbinden sich die Geräte mit anderen
|
||
Instanzen neu. Aktuell dauert dieser Prozess in unserer größten Stage mit etwa 2,5 Millionen Geräten knapp 3 Stunden. Da wir ja
|
||
Round-Robin für das Load Balancing nutzen, hat der Ersatz-Pod, der hier gestartet wurde, danach deutlich weniger offene
|
||
Verbindungen als die alten Pods. In der Praxis führt das nicht zu Problemen, denn die Last ist bei neuen Verbindungen mit
|
||
Abstand am höchsten.
|
||
|
||
Falls ein Pod (beispielsweise aufgrund eines Bugs) unkontrolliert beendet wird, versuchen sich alle Geräte auf einmal neu zu
|
||
verbinden. Das würde zur Überlastung des Systems führen, daher gibt es einen Rate Limiter, der dafür sorgt, dass sich Geräte
|
||
nicht zu schnell wieder verbinden können. Natürlich ist das ein ungünstiger Zustand, da die Funktionalität der noch nicht wieder
|
||
verbundenen Geräte eine ganze Weile eingeschränkt sein kann.
|
||
|
||
Jetzt kommen wir mal zum geplanten Fall: eine neue WSM-Version soll deployed werden. Das Deployment läuft dann so ab: In einem
|
||
ersten Schritt werden 1/3 der Instanzen durch Instanzen der neuen Version als Canary-Deployment ersetzt. Diese neue Version
|
||
läuft parallel zu der alten für eine Woche, bevor auch die übrigen Instanzen ersetzt werden. So können Fehler frühzeitig erkannt
|
||
und behoben werden, bevor alle Geräte betroffen sind.
|
||
|
||
[30] Das bedeutet übrigens nicht, dass nach dem Canary-Deployment 1/3 der Verbindungen auf der neuen Version stattfinden. Die
|
||
Wahrheit ist hier etwas komplizierter: die Geräte, die sich nach dem Abschalten mancher der alten Instanzen neu verbinden,
|
||
verbinden sich ja genauso häufig mit jeder der Canary-Instanzen wie mit jeder der alten Stable-Instanzen. In dem 7-Tage-Zeitraum
|
||
gleichen sich die Anzahl der verbundenen Geräte dann etwas aus, weil Geräte regelmäßig auch aus anderen Gründen die Verbindung
|
||
verlieren und sich neu verbinden. Nach einer Woche werden die übrigen 2/3 der Instanzen ersetzt und wie vorhin haben dann die
|
||
zuerst deployeten Canary-Instanzen mehr offene Verbindungen als die zuletzt deployeten. Wie gesagt führt das allerdings in der
|
||
Praxis zu keinen Problemen und gleicht sich auf Dauer von selbst aus.
|
||
|
||
Jetzt habt ihr gesehen, wie das System tatsächlich aussieht. Natürlich haben wir in den gut 5 Jahren, in denen das Projekt
|
||
existiert, auch dazugelernt und würden einige Dinge anders gestalten. Am Anfang des Vortrags habe ich ja schon gesagt, dass das
|
||
Ziel wäre, den WSM so selten wie möglich updaten zu müssen. Dafür ist es hilfreich, wenn der WSM so wenige Aufgaben wie möglich
|
||
bekommt. In einer idealen Welt sollte daher der WSM der kleinste Service im gesamten System sein. Die Realität ist: der WSM ist
|
||
der mit Abstand größte Service des Heimdall-Systems.
|
||
|
||
Woran liegt das? Aktuell hat der WSM einige Aufgaben:
|
||
|
||
* TLS und alles, was dazugehört: die Terminierung der TLS-Verbindung, die Validierung der Geräte-Zertifikate, die Ausnahmen zur
|
||
Validierung der Zertifikate und das Blocklisting von Zertifikaten.
|
||
* Der Websocket-Upgrade, also die Entgegennahme der initialen HTTP-Verbindung und der Wechsel zum Websocket-Protokoll
|
||
* Der Corporate Handshake, der zu Beginn jeder Verbindung stattfinden muss
|
||
* Das Message Routing an die Backends inklusive Offenhalten der Verbindungen und Warten auf Antworten
|
||
* Die Quarantäne-Logik
|
||
* Einige andere Workarounds, die im WSM diverse Spezialfälle abhandeln
|
||
|
||
Um also den WSM möiglichst klein zu bekommen, müssen möglichst viele dieser Aufgaben ausgelagert werden. Oder umgekehrt: die
|
||
Aufgaben, die unbedingt notwendig zum Halten der Verbindung sind, sollten aus dem WSM extrahiert werden.
|
||
|
||
[35] Bevor ich einen Vorschlag vorstelle, wie wir das erreichen könnten, will ich noch einmal ein bisschen detaillierter
|
||
erklären, wie das Websocket-Protokoll funktioniert. Das Gerät eröffnet zu Beginn eine TCP-Verbindung zum WSM. Es ist nicht
|
||
besonders wichtig zu wissen, was TCP genau macht, sondern nur, dass man bei einer TCP-Verbindung Daten in beide Richtungen
|
||
verschicken kann und dass die TCP-Verbindung jederzeit auf beiden Seiten geschlossen werden kann. Nach Öffnung der
|
||
zugrundeliegenden Verbindung findet der TLS-Handshake mit Verschlüsselung und Authentifizierung statt. Ab diesem Zeitpunkt
|
||
verläuft die Kommunikation verschlüsselt und der WSM kennt ein Zertifikat, das das jeweilige Gerät ausweist. Als nächstes wird
|
||
vom Gerät der Websocket-Endpunkt aufgerufen und der WSM wechselt das Protokoll zum Websocket-Protokoll. Ab hier können beliebige
|
||
Daten im Websocket-Protokoll zwischen Gerät und WSM hin und her geschickt werden. Dann passiert der Corporate Handshake und
|
||
schließlich der Austausch von beliebigen anderen Nachrichten, beispielsweise über den Status der Geräte. Die Verbindung
|
||
inklusive TLS-Terminierung muss von einem einzigen Server gehalten werden, wenn wir nicht komische Nichtstandard-Dinge mit
|
||
Verschlüsselung tun wollen, was aus Security-Gesichtspunkten natürlich keine gute Idee ist. Allerdings könnte die gesamte
|
||
Kommunikation, die nach der Entschlüsselung der Nachrichten, also unterhalb der ersten gestrichelten Linie, stattfindet,
|
||
außerhalb des Services stattfinden, der die Verbindung hält.
|
||
|
||
Hier wäre daher unser Vorschlag, um die Verbindungen noch länger halten zu können. Vor die übrigen Systeme wird ein Service
|
||
gesetzt, den ich hier "Connection Holder" genannt habe und der nur dafür zuständig ist, die TCP-Verbindung zu den Geräten zu
|
||
halten, die TLS-Verschlüsselung zu terminieren und zu Validieren, dass die Geräte-Zertifikate von einem bekannten Issuer
|
||
ausgestellt wurden. Nach der TLS-Terminierung wird die TCP-Verbindung einfach an das Äquivalent des jetzigen WSMs
|
||
weitergetunnelt. Wenn die WSM-Instanz beendet wird, kann der Tunnel an eine andere WSM-Instanz weitergeroutet werden, ohne die
|
||
Verbindung zum Gerät abzubrechen. Damit der WSM Zertifikatslogik wie Blocklisting durchführen kann, muss zu Beginn des
|
||
Verbindungsaufbaus zwischen Connection Holder und WSM das validierte Geräte-Zertifikat mitgeschickt werden. Außerdem müssen die
|
||
Verbindungen eine eindeutige ID bekommen, sodass die WSM-Instanzen beispielsweise persistieren können, ob für eine gegebene
|
||
Verbindung bereits der Corporate Handshake durchgeführt wurde. Natürlich könnten auch andere Aufgaben aus dem WSM ausgelagert
|
||
werden, hier mal exemplarisch das Message Routing inklusive Warten auf die Antwort des Backends.
|
||
|
||
[40] Schauen wir uns das ganze in der Laufzeitsicht etwas genauer an. Das Gerät öffnet also eine TCP-Verbindung inklusive TLS
|
||
zum Connection Holder. Diese Verbindung soll jetzt möglichst lange bestehen bleiben. Der Connection Holder erstellt eine
|
||
eindeutige Verbindungs-ID, die der WSM später nutzen kann, um Verbindungen zu identifizieren und ihren Status zu vergleichen.
|
||
Der Connection Holder sucht sich per Load Balancing eine WSM-Instanz, zu der er eine TCP-Verbindung öffnet. Das Gerät öffnet
|
||
eine Websocket-Verbindung zum Connection Holder, der wiederum eine Websocket-Verbindung zum WSM öffnet. Dort wird überprüft, ob
|
||
das validierte Geräte-Zertifikat akzeptiert werden soll und gegebenenfalls kann der WSM an dieser Stelle die Verbindung sofort
|
||
beenden. Andernfalls wird die Connection-ID persistiert, mit dem Status "hier existiert eine Verbindung, für die aber noch kein
|
||
Corporate Handshake durchgeführt wurde". Die Antworten "101 Switching Protocols" sorgen dafür, dass die jeweiligen
|
||
Websocket-Verbindungen geöffnet sind. Alle weiteren Nachrichten werden vom Connection Holder zwischen Gerät und WSM
|
||
weitergetunnelt. Jetzt kann der WSM also wie gehabt den Corporate Handshake durchführen, würde danach auch wieder einen Status
|
||
für die jeweilige Verbindung persistieren, und könnte dann Nachrichten wie zuvor weiterleiten. Wenn jetzt die TCP-Verbindung vom
|
||
WSM beendet wird, öffnet der Connection Holder eine TCP-Verbindung zu einer anderen WSM-Instanz und versucht, auch dorthin eine
|
||
Websocket-Verbindung zu etablieren. Durch die persistierte Connection-ID erkennt die zweite WSM-Instanz, dass der Corporate
|
||
Handshake bereits durchgeführt wurde und behandelt die Verbindung entsprechend. Ab diesem Zeitpunkt werden Nachrichten an die
|
||
zweite WSM-Instanz weitergetunnelt. Das Gerät merkt davon nichts.
|
||
|
||
Von innen betrachtet würde der Connection Holder so aussehen: Außen liegt der TCP Connector, der die TCP-Verbindung zum Gerät
|
||
entgegennimmt und die Connection-ID erstellt. Dann kommt ein Filter, der für die TLS-Terminierung inklusive Extraktion des
|
||
Geräte-Zertifikats zuständig ist. Zum Schluss noch der Websocket-Filter, der die Websocket-Verbindungen zum WSM verwaltet.
|
||
|
||
Was wären die Nachteile des vorgeschlagenen Refactorings? Zum einen natürlich die Entwicklungskosten, bestehend aus den
|
||
Entwicklungskosten des Connection Holders, den notwendigen Refactorings im WSM sowie den notwendigen ausführlichen Tests, um zu
|
||
gewährleisten, dass das System funktioniert wie geplant. Zum anderen käme in die Servicelandschaft bei Heimdall ein weiterer
|
||
Service hinzu, der potenziell gewartet und beim Onboarding neuer Entwickler:innen berücksichtigt werden muss. Allerdings können
|
||
die Nachteile relativiert werden, und es gibt auch einige Vorteile: zum einen ist das notwendige Refactoring im WSM minimal,
|
||
denn nur die Logik für das Persistieren und Überprüfen des Verbindungsstatus kommt hinzu. Die Entwicklung des Connection Holder
|
||
ist auch nicht sonderlich aufwändig, da er relativ wenige Aufgaben hat. Entsprechend hält sich auch der Overhead beim Onboarding
|
||
in Grenzen. Der große Vorteil allerdings ist, dass der Connection Holder äußerst selten Updates benötigt. Hier ist zu erwarten,
|
||
dass die Businesslogik sich sehr selten ändert, also werden Updates hauptsächlich aus Security-Gründen nötig werden. Der große
|
||
Vorteil ist jetzt, dass WSM-Updates ohne Verbindungsneustarts möglich werden. Insbesondere führt das dazu, dass die Updates des
|
||
WSM deutlich schneller stattfinden können und außen liegende Systeme weniger beeinflussen. Das führt zu einer verbesserten
|
||
Time-To-Market bei neuen Features und zu verringerten Abhängigkeiten und Kommunikations-Overheads zu anderen Teams.
|
||
|
||
Zusammenfassend können wir schon im aktuellen System zuverlässig dafür sorgen, dass Konfiguration schnell und unkompliziert ohne
|
||
Neuverbindungen geändert werden kann. Neuverbindungen komplett zu vermeiden dürfte nicht möglich sein, aber wir haben Ideen, wie
|
||
wir uns in diese Richtung verbessern können. Ich hoffe, ich konnte euch einen guten Einblick in die Herausforderungen geben, vor
|
||
die uns die langlaufenden Verbindungen in Zusammenhang mit Systemupdates stellen.
|
||
|
||
Hier seht ihr noch einmal, wie ihr mich erreichen könnt. Danke fürs Zuhören!
|