Entwickeln hochverfügbarer Anwendungen mit dem Azure IoT Operations MQTT-Broker
Das Erstellen einer hochverfügbaren Anwendung mit dem MQTT-Broker umfasst sorgfältige Überlegungen zu Sitzungstypen, QoS (Quality of Service), Nachrichtenbestätigungen, paralleler Nachrichtenverarbeitung, Nachrichtenaufbewahrung und gemeinsamer Abonnements. Der MQTT-Broker verfügt über einen verteilten, speicherinternen Nachrichtenbroker sowie Speicher, der Nachrichtenaufbewahrung und integrierte Zustandsverwaltung mit MQTT-Semantik bereitstellt.
In den folgenden Abschnitten werden die Einstellungen und Features erläutert, die zu einer robusten und verteilten Anwendung ohne Nachrichtenverluste beitragen.
Quality of Service (QoS, Servicequalität)
Sowohl Herausgeber als auch Abonnenten sollten QoS-1 verwenden, um die Nachrichtenzustellung mindestens einmal zu gewährleisten. Der MQTT-Broker speichert und überträgt Nachrichten erneut, bis er eine Bestätigung (ACK) vom Empfänger empfängt, um sicherzustellen, dass während der Übertragung keine Nachrichten verloren gegangen sind.
Sitzungstyp und Clean-Session-Flag
Legen Sie zum Sicherstellen, dass keine Nachrichtenverluste auftreten, das clean-start--Flag auf „false“ fest, wenn Sie eine Verbindung mit dem MQTT-Broker herstellen. Diese Einstellung weist den Broker an, den Sitzungszustand für den Client beizubehalten, wodurch Abonnements und nicht bestätigte Nachrichten zwischen Verbindungen erhalten bleiben. Wenn der Client die Verbindung trennt und später erneut eine Verbindung herstellt, wird an der Stelle fortgesetzt, an der die Unterbrechung aufgetreten ist, und alle nicht bestätigten QoS-1-Nachrichten werden mittels Wiederholung der Nachrichtenzustellung empfangen. Wenn konfiguriert, lässt der MQTT-Broker die Clientsitzung ablaufen, wenn der Client nicht innerhalb des Sitzungsablaufintervalls wieder eine Verbindung herstellt. Der Standardwert ist ein Tag.
„Receive-Max“ in Multithreadanwendungen
Multithreadanwendungen sollten receive-max (max. 65.535) verwenden, um Nachrichten parallel zu verarbeiten und die Ablaufsteuerung anzuwenden. Diese Einstellung optimiert die Nachrichtenverarbeitung, indem mehrere Threads gleichzeitig an Nachrichten arbeiten können, ohne dass der Broker dabei die Anwendung mit einer hohen Nachrichtenrate über die Anwendungskapazität hinaus überlastet. Jeder Thread kann eine Nachricht unabhängig verarbeiten und seine Bestätigung nach Abschluss senden. Eine typische Methode besteht darin, max-receive proportional zur Anzahl der von der Anwendung verwendeten Threads zu konfigurieren.
Bestätigen von Nachrichten
Wenn eine Abonnentenanwendung eine Bestätigung für eine QoS-1-Nachricht sendet, übernimmt sie den Besitz der Nachricht. Nach Empfang der Bestätigung für eine QoS-1-Nachricht beendet der MQTT-Broker die Nachverfolgung der Nachricht für diese Anwendung und dieses Thema. Die ordnungsgemäße Übertragung des Besitzes stellt den Erhalt von Nachrichten im Falle von Verarbeitungsproblemen oder Anwendungsabstürzen sicher. Wenn sich eine Anwendung vor einem Anwendungsabsturz schützen möchte, sollte die Anwendung den Besitz erst übernehmen, nachdem ihre Verarbeitung dieser Nachricht erfolgreich abgeschlossen wurde. Anwendungen, die den MQTT-Broker abonnieren, sollten die Bestätigung von Nachrichten verzögern, bis die Verarbeitung abgeschlossen ist, bis zu dem receive-max-Wert mit einem Maximalwert von 65.535. Dazu muss möglicherweise die Nachricht oder ein Ableitung der Nachricht an den MQTT-Broker zur weiteren Zustellung weitergeleitet werden.
Nachrichtenaufbewahrung und Brokerverhalten
Der Broker bewahrt Nachrichten auf, bis er eine Bestätigung von einem Abonnenten erhält, wodurch sichergestellt wird, dass keine Nachrichten verloren gehen. Dieses Verhalten garantiert, dass Nachrichten auch dann nicht verloren gehen, wenn eine Abonnentenanwendung abstürzt oder vorübergehend die Verbindung verliert, und dass sie nach der erneuten Herstellung der Verbindung der Anwendung verarbeitet werden können. MQTT-Broker-Nachrichten können möglicherweise ablaufen, wenn dies durch das Nachrichtenablaufintervall (Message-Expiry) konfiguriert ist und ein Abonnent die Nachricht nicht verwendet hat.
Aufbewahrte Nachrichten
Aufbewahrte Nachrichten behalten den temporären Anwendungszustand, z. B. als den aktuellen Status oder den aktuellen Wert für ein bestimmtes Thema. Wenn ein neuer Client ein Thema abonniert, empfängt er die letzte aufbewahrte Nachricht, um sicherzustellen, dass er über die aktuellsten Informationen verfügt.
Keep-Alive
Um eine hohe Verfügbarkeit bei Verbindungsfehlern oder -unterbrechungen sicherzustellen, legen Sie geeignete Keep-Alive-Intervalle für die Clientserverkommunikation fest. Während Leerlaufphasen senden Clients PINGREQs, und erwarten daraufhin PINGRESPs. Wenn keine Antwort erfolgt, implementieren Sie eine Logik für die automatische erneute Herstellung der Verbindung im Client, um Verbindungen erneut herzustellen. Die meisten Clients wie Paho verfügen über eine integrierte Wiederholungslogik. Da der MQTT-Broker fehlertolerant ist, ist eine erneute Verbindungsherstellung erfolgreich, wenn mindestens zwei fehlerfreie Brokerinstanzen, ein Front-End und ein Back-End, vorhanden sind.
Letztliche Konsistenz mit QoS-1-Abonnement
MQTT-Abonnements mit QoS-1 sorgen letztendlich für Konsistenz zwischen identischen Anwendungsinstanzen, indem sie ein freigegebenes Thema abonnieren. Wenn Nachrichten veröffentlicht werden, empfangen und replizieren Instanzen Daten mit mindestens einmaliger Zustellung. Die Instanzen müssen Duplikate behandeln und temporäre Inkonsistenzen tolerieren, bis die Daten synchronisiert wurden.
Gemeinsame Abonnements
Gemeinsame Abonnements ermöglichen den Lastenausgleich über mehrere Instanzen einer hochverfügbaren Anwendung. Anstatt dass jeder Abonnent, eine Kopie jeder Nachricht erhält, werden die Nachrichten gleichmäßig auf die Abonnenten verteilt. Der MQTT-Broker unterstützt derzeit nur einen Roundrobin-Algorithmus zum Verteilen von Nachrichten, was die Aufskalierung einer Anwendung erlaubt. Ein typischer Anwendungsfall besteht darin, mehrere Pods mithilfe von Kubernetes ReplicaSet bereitzustellen, die alle den MQTT-Broker mit demselben Themenfilter im gemeinsamen Abonnement abonnieren.
Zustandsspeicher
Der Zustandsspeicher ist eine replizierte speicherinterne HashMap zum Verwalten des Anwendungsverarbeitungszustands. Im Gegensatz zu etcd priorisiert der Zustandsspeicher z. B. Hochgeschwindigkeitsdurchsatz, horizontale Skalierung und niedrige Latenz durch In-Memory-Datenstrukturen, Partitionierung und Kettenreplikation. Es ermöglicht Anwendungen, die verteilte Natur und Fehlertoleranz des Zustandsspeichers zu verwenden, während sie schnell instanzenübergreifend auf einen konsistenten Zustand zugreifen. So verwenden Sie den integrierten Schlüssel-Wert-Speicher, der vom verteilten Broker bereitgestellt wird
Implementieren Sie kurzlebige Speicher- und Abrufvorgänge mithilfe der Schlüssel-Wert-Speicher-API des Brokers, um eine ordnungsgemäße Fehlerbehandlung und Datenkonsistenz sicherzustellen. Der kurzlebige Zustand ist ein kurzlebiger Datenspeicher, der bei zustandsbehafteter Verarbeitung verwendet wird, um schnellen Zugriff auf Zwischenergebnisse oder Metadaten während Echtzeitberechnungen zu erhalten. Im Kontext der Hochverfügbarkeitsanwendung hilft ein kurzlebiger Zustand beim Wiederherstellen von Anwendungszuständen zwischen Abstürzen. Er kann auf den Datenträger geschrieben werden, bleibt aber temporär, im Gegensatz zu Cold Storage, der für die langfristige Speicherung selten verwendeter Daten konzipiert ist.
Verwenden Sie den Zustandsspeicher zum Teilen von Zustands-, Zwischenspeicherungs-, Konfigurations- oder anderen wichtigen Daten zwischen mehreren Instanzen der Anwendung, sodass sie eine konsistente Ansicht der Daten behalten können.
Verwenden der integrierten Dapr-Integration des MQTT-Brokers
Für einfachere Anwendungsfälle könnte eine Anwendung Dapr (Distributed Apps Runtime) verwenden. Dapr ist eine portierbare, ereignisgesteuerte Open-Source-Runtime, die das Erstellen von Microservices und verteilten Anwendungen vereinfacht. Sie bietet eine Reihe von Bausteinen, z. B. Dienst-zu-Dienst-Aufrufe, Zustandsverwaltung und Veröffentlichen/Abonnieren von Nachrichten.
Dapr wird als Teil des MQTT-Brokers angeboten und abstrahiert Details der MQTT-Sitzungsverwaltung, von Nachrichten-QoS und -Bestätigung sowie des integrierten Schlüssel-Wert-Speichers, wodurch sie eine praktische Wahl für die Entwicklung einer hochverfügbaren Anwendung für einfache Anwendungsfälle darstellt, indem:
Entwerfen Sie Ihre Anwendung mithilfe der Dapr-Bausteine, z. B. Zustandsverwaltung für die Behandlung des Schlüssel-Wert-Speichers, und Veröffentlichen/Abonnieren von Nachrichten für die Interaktion mit dem MQTT Vermittler. Wenn für den Anwendungsfall Bausteine und Abstraktionen erforderlich sind, die von Dapr nicht unterstützt werden, sollten Sie die zuvor erwähnten Features des MQTT-Brokers verwenden.
Implementieren Sie die Anwendung mithilfe Ihrer bevorzugten Programmiersprache und Ihres Frameworks, indem Sie Dapr-SDKs oder -APIs für die nahtlose Integration in den Broker und den Schlüssel-Wert-Speicher nutzen.
Checkliste für die Entwicklung einer hochverfügbaren Anwendung
- Wählen Sie eine geeignete MQTT-Clientbibliothek für Ihre Programmiersprache aus. Der Client sollte MQTT v5 unterstützen. Verwenden Sie eine C- oder Rust-basierte Bibliothek, wenn Ihre Anwendung latenzempfindlich ist.
- Konfigurieren Sie die Clientbibliothek so, dass eine Verbindung mit dem MQTT-Broker hergestellt wird, wobei das clean-session-Flag auf
false
und die gewünschte QoS-Ebene (QoS-1) festgelegt ist. - Entscheiden Sie sich für einen geeigneten Wert für den Ablauf von Sitzungen, für den Ablauf von Nachrichten sowie für Keep-Alive-Intervalle.
- Implementieren Sie die Nachrichtenverarbeitungslogik für die Abonnentenanwendung, einschließlich des Sendens einer Bestätigung, wenn die Nachricht erfolgreich zugestellt oder verarbeitet wurde.
- Konfigurieren Sie für Multithreadanwendungen den Parameter max-receive, um die parallele Nachrichtenverarbeitung zu ermöglichen.
- Nutzen sie aufbewahrte Nachrichten, um den temporären Anwendungszustand beizubehalten.
- Verwenden Sie den verteilten Zustandsspeicher, um den kurzlebigen Anwendungszustand zu verwalten.
- Evaluieren Sie Dapr für die Entwicklung Ihrer Anwendung, wenn Ihr Anwendungsfall einfach ist und keine detaillierte Kontrolle der MQTT-Verbindung oder der Nachrichtenverarbeitung erfordert.
- Implementieren Sie gemeinsame Abonnements, um Nachrichten gleichmäßig auf mehrere Instanzen der Anwendung zu verteilen, was eine effiziente Skalierung ermöglicht.