NYSSR.NET / RESOURCES
Ein Nachrichtenmodell für das ganze Netz
Wie nyssr.net ein asynchrones Nachrichtenmodell für lokale Aufrufe, verteilte Workflows, Events, Responses und knotenübergreifendes Routing nutzt.
Wenn ein System lokale Aufrufe, standortübergreifende Workflows, Events und Responses braucht, ohne separate Kommunikationsmodelle zu pflegen, kann eine konsistente Nachrichtengrenze den Integrationsaufwand senken.
In nyssr.net kommunizieren Dienste nicht primär über geteilten Zustand oder eine Kette von HTTP-Endpunkten. Sie kommunizieren, indem sie Nachrichten an Objekte senden, die auf demselben Knoten, auf einem anderen Knoten oder irgendwo im Mesh laufen können.
Eine Nachricht ist mehr als ein Datenpaket. Sie ist eine typisierte Arbeitseinheit mit Ziel, Transportanweisungen und einem Lebenszyklus, der Verarbeitung, Weiterleitung und eine Response umfassen kann.
Eine Nachricht, zwei Zuständigkeiten
Jede Nachricht trennt was gesagt wird von wie sie reist:
- Der Record trägt die Geschäftsdaten: Felder, Werte, Strukturen und Arrays.
- Der Envelope trägt die Transportinformationen: Absender, Empfänger, Ergebnisstatus, Priorität, Komprimierung, Verschlüsselung und Response-Verhalten.
Der Envelope kümmert sich um den Transport; der Record trägt die Daten.
Diese Trennung lässt dasselbe Nachrichtenformat für einen lokalen Request, eine knotenübergreifende Notification oder eine Response arbeiten, die durchs Mesh zurückläuft.
Kernidee: Ein Record beschreibt die Arbeit; ein Envelope macht die Arbeit zustellbar, beobachtbar und steuerbar.
Typisierte Daten ohne starke Service-Kopplung
Records lassen sich dynamisch zusammenbauen, aber die meisten Produktionsnachrichten sind in JSON oder XML beschrieben. Aus dieser Beschreibung können Anwendungen typisierte Klassen zum Erzeugen und Lesen von Nachrichten generieren.
Eine Record-Definition kann so aussehen:
{
"name": "NODE_ADDED",
"description": "A remote node joined the network.",
"slots": [
{ "name": "REMOTE_NODE", "type": "NODE_ADDRESS" },
{ "name": "TYPE", "type": "STRING" }
]
}
Die wichtige Grenze ist der Nachrichtenvertrag, nicht die Implementierungsklasse hinter dem Dienst. Ein Dienst kann über Zeit Felder ergänzen, während ältere Konsumenten weiter die Felder nutzen, die sie verstehen.
Asynchron per Voreinstellung
Das Senden einer Nachricht blockiert den Absender nicht, bis der Empfänger fertig ist. Der Absender registriert oder ruft einen Handler auf und arbeitet weiter. Trifft die Nachricht ein, ruft das System den Handler im Verarbeitungskontext des Ziels auf.
Dieses Modell ist nützlich, wenn ein Dienst:
- Arbeit starten muss, die mehrere andere Dienste einbezieht
- Beobachter benachrichtigen will, ohne auf sie zu warten
- Viele unabhängige Requests verarbeitet
- Die Anwendung responsiv hält, während ein Ergebnis entsteht
Ein Handler kann ein Ergebnis zurückgeben, eine Notification senden, die Nachricht weiterleiten oder zurückhalten, bis ein anderer interner Request abgeschlossen ist.
Responses bilden einen eingebauten Handshake
Nachrichten können eine Response anfordern. Nach der Verarbeitung kann der Empfänger die Nachricht mit Ergebniscode und optionalem Ergebnistext zurückgeben. Der Absender weiß also, ob der Request erfolgreich war, fehlschlug oder sein Ziel nicht erreichte.
Dieser Handshake ist Teil des Nachrichtenlebenszyklus statt einer zusätzlichen API-Konvention. Er unterstützt gewöhnliche Requests ebenso wie Notifications, Broadcasts und mehrstufige Workflows.
Nachrichten verbinden Objekte direkt, unabhängig vom Knoten, auf dem sie laufen.
Durch das Knoten-Mesh geroutet
Der Absender muss für jede Nachricht keine neue Verbindung zum Empfänger öffnen. Knoten halten Kanäle zu ihren Nachbarn und leiten Nachrichten über die beste verfügbare Route weiter.
Routen haben Kosten, die von Verbindungsbedingungen wie der Weiterleitungszeit abhängen. Jeder Knoten beobachtet das Netz und kann einen anderen Weg wählen, wenn eine Verbindung ausfällt oder eine bessere Route verfügbar wird.
- Lokale Nachrichten bleiben lokal
- Remote-Nachrichten nutzen bestehende Knotenkanäle
- Fehlende Verbindungen können umgangen werden
- Der Empfänger kann in einer Cloud, Zweigstelle oder einem privaten Netz stehen
Das Mesh wählt eine passende Route statt auf einen zentralen Broker zu setzen.
Mehr als Request und Response
Dasselbe Nachrichtenmodell unterstützt mehrere Kommunikationsmuster:
- Requests bitten ein Ziel um Arbeit und erwarten ein Ergebnis
- Notifications kündigen ein Ereignis ohne erwartete Antwort an
- Broadcasts erreichen mehrere interessierte Ziele
- Weitergeleitete Nachrichten laufen über einen anderen Dienst oder Knoten weiter
- Zurückgestellte Nachrichten bleiben aktiv, bis ein Workflow abgeschlossen ist
Nachrichten können auch Prioritätsinformationen tragen. Antworten und Kontrollnachrichten können vor nachrangigem Verkehr bearbeitet werden. Komprimierung und Verschlüsselung lassen sich pro Nachricht anfordern oder pro Knoten konfigurieren.
Kernidee: Eine Kommunikationsprimitivität unterstützt lokale Aufrufe, verteilte Workflows, Events und belastbares knotenübergreifendes Routing.
Was das für das Anwendungsdesign ändert
Mit Nachrichten als Grenze zwischen Diensten müssen Anwendungen nicht wissen, wo jeder Dienst läuft oder wie er implementiert ist. Sie brauchen einen Nachrichtenvertrag und eine Zielidentität.
So lässt sich ein Dienst näher an seine Daten verlagern, mehrere Instanzen für Load Balancing betreiben oder seine Implementierung ersetzen, ohne jeden Aufrufer umzuschreiben.
Vertrag: Definieren Sie die ausgetauschten Daten zwischen Diensten unabhängig von deren internen Klassen.
Nebenläufigkeit: Lassen Sie Handler und Ziele asynchron arbeiten, statt Threads zu blockieren.
Resilienz: Nutzen Sie Ergebniscode, Responses, Weiterleitung und Alternativrouten, um Fehler sichtbar und behebbar zu machen.
Für die API-Details geht es weiter mit der Messages-Dokumentation. Für die gesamte Architektur zurück zur nyssr.net-Übersicht.