Das MQTT-Publish/Subscribe-Modell ist der Grund, warum ein Temperatursensor, ein Dashboard und ein Abrechnungsdienst Daten teilen können, ohne jemals die Adresse des anderen zu kennen. In diesem Artikel erfahren Sie, wie sich Pub/Sub von Request/Response unterscheidet, was die drei Arten der Entkopplung in der Praxis bedeuten, und Sie weisen jede davon selbst nach, mit zwei Terminalfenstern, die mit einem kostenlosen Broker verbunden sind.
Request/Response vs. Publish/Subscribe
Die meisten Entwickler lernen Netzwerkkommunikation über HTTP. Ein Client öffnet eine Verbindung zu einem bekannten Server, stellt eine Frage und wartet auf die Antwort. Dieses Muster ist einfach, koppelt die beiden Parteien aber eng: Der Client muss die Adresse des Servers kennen, der Server muss genau in diesem Moment laufen, und der Client blockiert (oder pollt), bis eine Antwort kommt.
Publish/Subscribe löst diese Kopplung, indem es einen Vermittler einfügt. Bei MQTT ist dieser Vermittler der Broker. Clients sprechen nie miteinander, sondern nur mit dem Broker:
- Ein Publisher sendet eine Nachricht mit einem Topic wie
plant1/line2/press/temperature, etwa ein Edge-Gateway, das Werte einer SPS an der Presse ausliest. - Ein Subscriber teilt dem Broker mit, welche Topics ihn interessieren, optional mit Wildcards wie
plant1/+/press/#. - Der Broker gleicht jede eingehende Nachricht mit allen aktiven Abonnements ab und leitet eine Kopie an jeden Treffer weiter.
Wenn die Rolle des Servers in der Mitte neu für Sie ist, behandelt unser Leitfaden was ein MQTT-Broker macht Routing, Sessions und Retained-Zustand ausführlicher.
| Aspekt | Request/Response (HTTP) | MQTT Publish/Subscribe |
|---|---|---|
| Wer kennt wen | Client kennt die Serveradresse | Clients kennen nur den Broker |
| Richtung | Client holt ab | Broker stellt bei Eingang zu |
| Fan-out an viele Leser | Eine Anfrage pro Leser | Ein Publish, viele Zustellungen |
| Verbindung | Oft kurzlebig | Eine langlebige TCP-Verbindung |
| Empfänger offline | Anfrage schlägt fehl | Persistente Sessions können puffern |
Die drei Arten der Entkopplung im MQTT-Publish/Subscribe-Modell
Die Fachliteratur zu Pub/Sub beschreibt meist drei Dimensionen der Entkopplung. Es lohnt sich, sie zu trennen, weil jede ein anderes IoT-Problem löst.
Räumliche Entkopplung
Publisher und Subscriber kennen weder IP-Adresse noch Hostnamen des anderen, nicht einmal, wie viele es gibt. Ein Sensor publiziert auf site/tank3/level; ob null, eine oder fünfzig Anwendungen das empfangen, sieht der Sensor nicht. Genau das erlaubt es, nächstes Jahr einen neuen Analysedienst hinzuzufügen, ohne die Firmware Tausender bereits ausgelieferter Geräte anzufassen.
Zeitliche Entkopplung
Publisher und Subscriber müssen nicht gleichzeitig online sein. MQTT bietet dafür zwei Mechanismen:
- Retained Messages. Der Broker hält die letzte retained Message pro Topic vor und übergibt sie jedem neuen Subscriber sofort. Ein Dashboard, das um 09:00 Uhr startet, sieht trotzdem den Ventilzustand, der um 06:00 Uhr publiziert wurde.
- Persistente Sessions. Ein Subscriber, der sich mit Clean Start auf false verbindet (und in MQTT 5 mit einem Session-Expiry-Intervall), behält seine Abonnements während der Trennung, und der Broker puffert Nachrichten mit QoS 1 und QoS 2 für ihn.
Die zeitliche Entkopplung ist nicht unbegrenzt. Warteschlangen sind durch die Session Expiry und die Kontingente des Brokers begrenzt, betrachten Sie sie also als Puffer für kurze Ausfälle, nicht als Langzeitspeicher.
Entkopplung der Synchronisation
Keine Seite blockiert die andere. Ein Publisher übergibt seine Nachricht an die Client-Bibliothek und macht weiter; die Bibliothek kümmert sich im Hintergrund um die Bestätigungen. Subscriber erhalten Nachrichten über Callbacks, statt in einer Schleife zu warten. Auf einem Mikrocontroller bedeutet das, dass die Hauptschleife weiter Sensoren ausliest, während die Netzwerk-I/O asynchron abläuft.
Topics: der Vertrag zwischen Publishern und Subscribern
Weil es keine direkte Verbindung zwischen den Parteien gibt, ist die Topic-Zeichenkette der einzige gemeinsame Vertrag. Gutes Topic-Design ist bei MQTT daher wichtiger als URL-Design bei REST:
- Vom Allgemeinen zum Speziellen:
company/site/area/line/device/measurement. Diese Reihenfolge folgt der ISA-95-Anlagenhierarchie (Enterprise → Site → Area → Line → Cell) und ist die Grundlage eines Unified Namespace (UNS), in dem jedes System seine Daten an der passenden Stelle publiziert, zum Beispielacme/werk-stuttgart/montage/linie-1/zelle-3/temperatur. - Ebenen stabil und aussagekräftig halten, damit Wildcards nützlich bleiben.
- Niemals Geheimnisse oder personenbezogene Daten in Topic-Namen aufnehmen.
- Topics nicht mit
$beginnen; dieses Präfix ist für Broker-Topics wie$SYSreserviert. - Befehle von Telemetrie trennen, zum Beispiel
.../cmd/...gegenüber.../telemetry/....
Die Wildcard + passt auf genau eine Ebene und # auf beliebig viele nachfolgende Ebenen. Ein Historian könnte acme/# abonnieren, während ein Linienverantwortlicher nur acme/izmir/assembly/line4/+/status braucht. Genau diese Entkopplung macht den UNS so wertvoll: MES, ERP und Dashboards abonnieren die Ebene, die sie brauchen, ohne Punkt-zu-Punkt-Schnittstellen zur SPS. Mehr dazu im Artikel Sparkplug B und Unified Namespace.
Ausprobieren: zwei Clients auf broker.connectmq.com
Nichts macht das Modell schneller greifbar, als es in Aktion zu sehen. Installieren Sie die Mosquitto-Kommandozeilen-Clients (mosquitto_pub und mosquitto_sub) und öffnen Sie zwei Terminals. Wählen Sie ein zufälliges Suffix, damit Ihre Topics auf dem kostenlosen öffentlichen MQTT-Broker nicht mit denen anderer kollidieren. Denken Sie daran, dass dieser Broker für Tests gedacht und für alle lesbar ist, und publizieren Sie nichts Sensibles.
Schritt 1: Einen Subscriber starten
# Terminal A: mit Wildcard abonnieren
mosquitto_sub -h broker.connectmq.com -p 1883 -i sub-demo-7f3a \
-t "connectmq/demo/7f3a/#" -v
Schritt 2: Von einem anderen Client publizieren
# Terminal B: zwei Messwerte publizieren
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-demo-7f3a \
-t "connectmq/demo/7f3a/room1/temperature" -m "21.4"
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-demo-7f3a \
-t "connectmq/demo/7f3a/room2/temperature" -m "19.8"
Terminal A gibt beide Nachrichten mit ihren Topics aus. Der Publisher hat nie erfahren, wo der Subscriber war: Das ist räumliche Entkopplung.
Schritt 3: Zeitliche Entkopplung mit einer retained Message nachweisen
Beenden Sie den Subscriber mit Strg+C. Publizieren Sie nun einen retained Wert, während niemand zuhört:
mosquitto_pub -h broker.connectmq.com -p 1883 -i pub-demo-7f3a \
-t "connectmq/demo/7f3a/door/state" -m "open" -r
Starten Sie den Subscriber erneut. Er empfängt sofort connectmq/demo/7f3a/door/state open, obwohl die Nachricht gesendet wurde, während er offline war. Zum Aufräumen publizieren Sie eine leere retained Payload mit -r -n.
Schritt 4: Fan-out
Öffnen Sie ein drittes Terminal mit einem weiteren Subscriber (mit einer anderen Client ID wie sub2-demo-7f3a). Publizieren Sie einmal, und beide Subscriber empfangen die Nachricht. Ein Publish, viele Zustellungen, und der Code des Publishers hat sich nicht geändert.
Ein programmatischer Subscriber in Python
Dasselbe Modell im Code zeigt die Entkopplung der Synchronisation: Der Callback wird ausgelöst, sobald Daten eintreffen, während Ihr Programm frei für andere Arbeit bleibt.
import time
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
PREFIX = "connectmq/demo/7f3a"
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(f"{PREFIX}/#", qos=1)
def on_message(client, userdata, msg):
print(f"{msg.topic} -> {msg.payload.decode()} (retained={msg.retain})")
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="py-sub-7f3a")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=60)
client.loop_start()
try:
while True:
# Ihre Anwendung arbeitet weiter; Nachrichten kommen im Hintergrund an.
time.sleep(5)
client.publish(f"{PREFIX}/heartbeat", str(int(time.time())), qos=1)
except KeyboardInterrupt:
client.loop_stop()
client.disconnect()
Warum Pub/Sub so gut zum IoT passt
- Unzuverlässige Verbindungen. Geräte im Mobilfunk oder WLAN fallen regelmäßig aus. Persistente Sessions und QoS 1/2 lassen sie ohne eigene Wiederholungslogik aufholen. Der Leitfaden zu MQTT-QoS-Stufen erklärt die Zustellgarantien im Detail.
- Viele Konsumenten pro Datenpunkt. Derselbe Vibrationsmesswert kann ein Dashboard, ein Alarmskript und einen Historian speisen. Jeder abonniert unabhängig.
- Nur ausgehende Verbindungen. Geräte öffnen eine Verbindung zum Broker; nichts muss sich in das Gerät hinein verbinden. Das ist für NAT und Firewalls weit freundlicher, als auf jedem Sensor einen HTTP-Server zu betreiben.
- Kleine Pakete. Der feste Header kann zwei Bytes groß sein, was Funkzeit und Datentarife schont.
Typische Stolperfallen und wie Sie sie vermeiden
Kein Subscriber ist kein Fehler. Publizieren Sie auf ein Topic ohne Subscriber, nimmt der Broker die Nachricht an und verwirft sie (sofern sie nicht retained ist). Entwickler vermuten bei einer verlorenen Nachricht manchmal ein Netzwerkproblem, obwohl es in Wahrheit ein Tippfehler im Topic ist. Abonnieren Sie beim Debuggen # unter Ihrem Präfix.
Doppelte Client IDs. Zwei Clients mit derselben ID werfen sich gegenseitig in einer Schleife hinaus. Jede Verbindung braucht eine eindeutige ID.
Zu breite Wildcards im Produktivbetrieb. Ein Service, der # abonniert, erhält alles, auch Datenverkehr, den er nicht verarbeiten kann. Beschränken Sie Abonnements auf die Ebenen, die Sie brauchen.
Antworten erwarten. Pub/Sub hat keine eingebaute Antwort. Wenn Sie Request/Response-Semantik brauchen, ergänzt MQTT 5 ein Response Topic und Correlation Data, beschrieben in unserem Überblick über die Funktionen von MQTT 5.
Reihenfolge über Topics hinweg. MQTT bewahrt die Reihenfolge pro Topic für eine bestimmte QoS von einem Publisher, nicht aber über verschiedene Topics hinweg. Fügen Sie Payloads einen Zeitstempel oder eine Sequenznummer hinzu, wenn die Reihenfolge wichtig ist.
Von der Demo zur Produktion
Der öffentliche MQTT-Broker ist ideal für Experimente, wird aber gemeinsam genutzt und ist für alle lesbar. Für echte Geräte brauchen Sie Authentifizierung, TLS auf Port 8883 und Ihren eigenen isolierten Namensraum. Ein verwalteter MQTT-Broker wie ConnectMQ bietet genau das: Erstellen Sie im Portal einen Broker, kopieren Sie den generierten Benutzernamen, das Passwort und die Client ID und richten Sie denselben Code auf Port 8883 mit TLS. ConnectMQ unterstützt MQTT 3.1.1 und 5.0, sodass Retained Messages, Session Expiry und Shared Subscriptions so funktionieren, wie in diesem Artikel beschrieben. Für einen umfassenderen Rundgang durch das Protokoll beginnen Sie mit unserem vollständigen MQTT-Tutorial, oder lesen Sie auf Paketebene, wie MQTT funktioniert.
Starten Sie mit ConnectMQ
Bereit, Ihren Pub/Sub-Prototyp auf einen privaten Broker zu bringen? Registrieren Sie sich unter app.connectmq.com und erstellen Sie in wenigen Minuten einen kostenlosen Serverless Broker, ganz ohne Kreditkarte. Mit dem MQTT-Client im Browser und dem Live-Topic-Explorer von ConnectMQ beobachten Sie Publishes und Abonnements, ohne etwas zu installieren.
Häufig gestellte Fragen
Ist MQTT Publish/Subscribe dasselbe wie eine Message Queue?
Nicht ganz. Bei MQTT erhält jeder passende Subscriber seine eigene Kopie jeder Nachricht, während eine klassische Queue jede Nachricht an genau einen Konsumenten zustellt. Shared Subscriptions in MQTT 5 ergänzen bei Bedarf eine Lastverteilung wie bei einer Queue.
Kann ein Client gleichzeitig publizieren und abonnieren?
Ja. Eine einzige MQTT-Verbindung kann auf einige Topics publizieren und andere abonnieren, und so empfangen die meisten Geräte Befehle, während sie Telemetrie senden.
Was passiert mit Nachrichten, wenn niemand abonniert hat?
Der Broker verwirft sie, es sei denn, die Nachricht ist retained; dann wird der letzte retained Wert pro Topic für künftige Subscriber gespeichert.
Wissen Publisher, wie viele Subscriber eine Nachricht erhalten haben?
Nein. Bestätigungen gibt es bei MQTT nur zwischen Client und Broker, und genau das hält Publisher und Subscriber entkoppelt.



