Verteilte Systeme
Prof. Dr. Alexandra Mikityuk
HTW Berlin
mosquitto_pub / mosquitto_sub oder Python einen ersten Pub/Sub-Test fahrenStellt euch vor: 1.000 Sensoren in einer Fabrik. 50 Apps wollen ihre Daten sehen. Ihr baut das mit HTTP aus VL 6.
đ Was wird damit richtig unangenehm?
Letzte VL: HTTP & REST â Client fragt, Server antwortet. Funktioniert prima fĂŒrs Web. Aber stellt euch das mal mit 1.000 Sensoren vor:
Der Server kann den Client nicht von sich aus ansprechen. Wer wissen will âist was Neues da?", muss regelmĂ€Ăig nachfragen â das heiĂt Polling.
Sensoren senden, wenn's was Neues gibt. Wer interessiert ist, abonniert.
Publish/Subscribe ist kein neues Konzept. Drei Beispiele aus eurem Leben:
Ihr abonniert die Zeitung. Der Verlag druckt und verteilt. Ihr wisst nicht, wer noch abonniert hat â das ist auch egal.
Der Sender weiĂ nicht, wer gerade hört. Er broadcastet. Wer das Programm möchte, schaltet ein â alle anderen verpassen es nichts.
Creator lÀdt Video hoch (publish), Abonnenten kriegen Benachrichtigung (subscribe). YouTube ist der Mittelsmann.
Schickt Nachrichten zu einem Topic â z.B. ein Sensor schickt Temperatur. WeiĂ nicht, wer das liest.
Das HerzstĂŒck. Nimmt Nachrichten an, sortiert sie nach Topic, schickt sie an alle, die abonniert haben.
Sagt dem Broker: âIch will alles vom Topic X." Wartet dann passiv auf neue Nachrichten.
Message Queuing Telemetry Transport â ein leichtgewichtiges Pub/Sub-Protokoll.
mosquitto.org â auf jedem Linux installierbar1883, mit TLS Port 8883)Konkretes Szenario: ein Sensor im Wohnzimmer, eine App auf dem Handy, ein Broker dazwischen.
home/wz/temphome/wz/temp# alle 60 Sekunden:
publish("home/wz/temp", "22.3")
Sensor weiĂ nicht, ob die App da ist. Schickt einfach zum Broker.
# beim Start:
subscribe("home/wz/temp")
# danach: jede neue Temperatur kommt rein
App muss nicht pollen â Broker schiebt die Werte aktiv durch.
Sechs Branchen, sechs Topic-Hierarchien â alle nach dem gleichen Muster grob â fein.
home/livingroom/temperature
home/kitchen/smoke
home/garage/door/state
home/all/lights/control
factory/line-A/machine-3/temp
factory/line-A/machine-3/rpm
factory/quality/line-B/defects
factory/energy/total/kwh
hospital/ward-3/bed-12/hr
hospital/ward-3/bed-12/spo2
hospital/icu/alerts/critical
hospital/pharmacy/inventory
traffic/berlin/junction-5/light
traffic/berlin/A100/flow
traffic/berlin/A100/incident
traffic/berlin/parking/p3/free
fleet/truck-42/location
fleet/truck-42/fuel
fleet/truck-42/door/cargo
fleet/dispatcher/orders/new
garden/zone-A/moisture
garden/zone-A/light
garden/weather/forecast
garden/pump/zone-A/control
domain / standort / gerĂ€t / messwert. Sucht euch eine Konvention und haltet sie konsequent durch â sonst wird die Wildcard-Suche spĂ€ter ein Albtraum.
Topics sind hierarchische Strings, getrennt mit / â fast wie ein Datei-Pfad. So bringt ihr Ordnung in tausende Nachrichten.
home/livingroom/temperature â konkret: Wohnzimmer
home/livingroom/humidity â anderes Sensor-Topic
home/kitchen/temperature â anderer Raum
home/garage/door/state â tiefer geschachtelt
factory/line-A/machine-3/status â industrielles Beispiel
standort / bereich / gerÀt / messwert. Klein-buchstaben, keine Leerzeichen.
Ihr betreut ein Smart Building: 50 RĂ€ume, jeder mit 5 Sensoren.
Das sind 250 Topics insgesamt. Eine Monitoring-App will alle Temperaturen sehen.
đ WĂŒrdet ihr im Code wirklich 50 mal subscribe(...) aufrufen?
Was, wenn ihr alle Temperaturen aus allen RĂ€umen wollt? DafĂŒr gibt's zwei Joker-Zeichen.
+Ersetzt genau eine Ebene des Topic-Pfads.
home/+/temperature
Matcht:
home/livingroom/temperature âhome/kitchen/temperature âhome/garage/door/state â (eine Ebene zu tief)#Ersetzt alles ab dieser Position. Darf nur am Ende stehen.
home/#
Matcht:
home/livingroom/temperature âhome/garage/door/state âfactory/line-A/machine-3 â (anderer Stamm)factory/# â und kriegt alles, was in der Fabrik passiert. Eine Raum-App nimmt home/livingroom/+.
Vier Subscribe-Patterns links, sieben publizierte Topics rechts. Welche Nachrichten kriegt wer?
home/livingroom/temperaturehome/+/temperaturehome/kitchen/#home/#| Topic | A | B | C | D |
|---|---|---|---|---|
home/livingroom/temperature | â | â | â | â |
home/kitchen/temperature | â | â | â | â |
home/kitchen/smoke | â | â | â | â |
home/kitchen/fridge/temp | â | â | â | â |
home/garage/door | â | â | â | â |
factory/line-A/temp | â | â | â | â |
home | â | â | â | â |
+ matcht genau eine Ebene â home/kitchen/fridge/temp hat zu viele fĂŒr home/+/temperature. Und home/# matcht nicht nur âhome" allein â es braucht mindestens eine Ebene danach.
mosquitto im TerminalAuf jedem Linux/Mac mit zwei Befehlen testbar. Probiert das daheim aus!
# Installation (einmalig):
$ brew install mosquitto # Mac
$ apt install mosquitto-clients # Linux
# Auf Topic hören:
$ mosquitto_sub -h "test.mosquitto.org" \
-t "htw/test/#"
Bleibt offen, wartet auf Nachrichten.
# Eine Nachricht senden:
$ mosquitto_pub -h "test.mosquitto.org" \
-t "htw/test/temp" \
-m "22.3"
# im ersten Terminal seht ihr:
22.3
Nachricht erscheint sofort im Subscriber.
test.mosquitto.org (Port 1883, ohne Passwort). Praktisch fĂŒr die Lab-Ăbung â keine eigene Installation nötig.
In Python heiĂt die Standard-Library paho-mqtt â pip install paho-mqtt. Hier ein minimaler Subscriber:
import paho.mqtt.client as mqtt
def on_message(client, userdata, msg):
print(f"{msg.topic}: {msg.payload.decode()}")
client = mqtt.Client()
client.on_message = on_message
client.connect("test.mosquitto.org", 1883)
client.subscribe("htw/test/#")
client.loop_forever()
import paho.mqtt.client as mqtt
import time, random
client = mqtt.Client()
client.connect("test.mosquitto.org", 1883)
while True:
temp = 20 + random.random() * 5
client.publish("htw/test/temp", str(temp))
time.sleep(5)
Drei Sensoren publizieren, drei Konsumenten abonnieren mit unterschiedlichen Wildcards â der Broker macht den Rest.
home/livingroom/temphome/garage/doorhome/kitchen/smokehome/# â bekommt alleshome/+/temp â nur Temperaturenhome/+/smoke + home/garage/door â nur Alarm-relevantes| Sensor publiziert auf | đ± Handy | đ Dashboard | đš Sirene |
|---|---|---|---|
home/livingroom/temp | â | â | â |
home/garage/door | â | â | â |
home/kitchen/smoke | â | â | â |
home/livingroom/temp â und schaltet ab 25°C auf rot. Niemand muss umkonfiguriert werden.
Drei verschiedene MQTT-Nachrichten gehen unterwegs verloren. Bei welcher davon ist das schlimm â und warum?
Sensor publiziert alle 60s.
Eine Messung geht verloren.
Schlimm?
Bewegungsmelder schlÀgt an.
Die Sirene kriegt's nicht mit.
Schlimm?
BestÀtigung wird dupliziert.
Kunde zahlt 2Ă das Gleiche.
Schlimm?
đ Soll MQTT fĂŒr alle drei dieselbe Garantie bieten? Oder braucht ihr verschiedene âSicherheitsstufen" pro Nachricht?
MQTT bietet drei Zustellungs-Garantien. Denkt sie wie verschiedene Versand-Arten:
âAt most once"
Wie eine Postkarte: rausgeschickt, fertig. Kann verloren gehen, kein Re-Try.
Nutzt fĂŒr: Temperatur-Sensor â nĂ€chste Messung kommt eh in 60s.
Mindestens 1Ă
Wie ein Einschreiben: EmpfĂ€nger bestĂ€tigt. Kommt sicher an â aber evtl. mehrfach.
Nutzt fĂŒr: Alarm-Nachricht â soll garantiert ankommen, Duplikat egal.
Genau 1Ă
Wie Einschreiben mit RĂŒckschein + ZĂ€hler. 4-Wege-Handshake, kein Duplikat.
Nutzt fĂŒr: Banking, Bestellungen â wo Duplikate schaden wĂŒrden.
In Python ist QoS ein einzelner Parameter â sowohl beim Publish als auch beim Subscribe.
# QoS 0 â Temperaturmessung
client.publish("home/wz/temp",
"22.3", qos=0)
# QoS 1 â Bewegungsalarm
client.publish("home/door/alarm",
"intrusion", qos=1)
# QoS 2 â Bezahlvorgang
client.publish("shop/payment",
payload_json, qos=2)
# Subscriber wÀhlt maximalen QoS
client.subscribe("home/+/temp", qos=0)
client.subscribe("home/+/alarm", qos=1)
client.subscribe("shop/payment", qos=2)
# Effektiver QoS = min(pub, sub)
# Publisher=2, Subscriber=1 â tatsĂ€chl. 1
qos=0, wenn ihr nichts angebt. Bewusst, weil's der hÀufigste Fall ist.
Funktionen, die euch das Leben leichter machen â kurz im Ăberblick:
Client sendet alle X Sekunden ein Mini-Ping. Wenn er ausfÀllt, merkt's der Broker und markiert ihn offline.
Broker speichert die letzte Nachricht pro Topic. Neue Subscriber kriegen sofort den letzten Stand â perfekt fĂŒr âaktuelle Temperatur".
Wenn ein Client ungeplant abstĂŒrzt, schickt der Broker eine vorher hinterlegte âAbschieds-Nachricht" â andere können reagieren.
Broker veröffentlicht eigene Statistiken (Clients, Bytes, Uptime) unter $SYS/.... Praktisch zum Monitoring.
Was passiert, wenn ein neuer Subscriber spĂ€t einsteigt? Genau dafĂŒr gibt's Retained Messages.
| Zeit | Was passiert | Broker speichert | Dashboard sieht |
|---|---|---|---|
| t=0s | Sensor: publish("home/temp", "22.1", retain=True) | 22.1 | noch nicht da |
| t=60s | Sensor: publish("home/temp", "22.3", retain=True) | 22.3 (ersetzt) | noch nicht da |
| t=120s | Sensor: publish("home/temp", "22.5", retain=True) | 22.5 (ersetzt) | noch nicht da |
| t=150s | đ± Dashboard startet + abonniert home/temp | 22.5 | 22.5 â sofort! |
| t=180s | Sensor: publish("home/temp", "22.6", retain=True) | 22.6 | 22.6 |
Dashboard startet â Broker hat nichts gespeichert â leeres Display, bis der Sensor das nĂ€chste Mal sendet (in bis zu 60s!).
Dashboard startet â Broker liefert sofort den letzten Wert â Display sofort gefĂŒllt. Perfekt fĂŒr aktuelle-Stand-Anzeigen.
retain=True. Events (Knopfdruck, Alarm) â retain=False.
| HTTP / REST | MQTT | |
|---|---|---|
| Kommunikationsmodell | Request / Response (Pull) | Publish / Subscribe (Push) |
| Overhead pro Nachricht | ~ 200-500 Byte (Header) | ~ 2-5 Byte (Mini-Header) |
| Wer ist âdumm"? | Client kennt Server-URL | Niemand kennt jemanden direkt |
| Stateful? | Zustandslos â jede Anfrage neu | Persistente Sessions möglich |
| Latenz fĂŒr Updates | Hoch (Polling) | Sehr niedrig (Push) |
| StÀrke | Web-APIs, anfragen + transformieren | IoT, Telemetrie, viele kleine GerÀte |
| Tools / Debugging | curl, Browser, Postman | mosquitto-CLI, MQTT-Explorer |
Home Assistant, Zigbee2MQTT, Tasmota â die meisten Bastler-Stacks im DIY-IoT.
Sensoren in Maschinen, SPS-Kopplung, OPC-UA-Bridges â MQTT ist hier de-facto Standard.
BMW, Daimler & Co nutzen MQTT fĂŒr Telemetrie zwischen Fahrzeug und Backend (Position, Status).
Der ursprĂŒngliche Einsatzfall â bis heute aktiv. Wenig Bandbreite, viele Sensoren.
Facebook Messenger nutzt MQTT seit Jahren fĂŒr Chat-Push auf Handys (akkuschonend).
DIY und kommerziell â Sensor-Netze melden Messwerte an zentrale Dashboards.
Eine konkrete Fertigungslinie. So sieht's in echt aus â und ihr seht direkt, warum Wildcards goldwert sind.
# Pattern: factory/{line}/{machine}/{sensor}
factory/line-A/machine-1/temp
factory/line-A/machine-1/rpm
factory/line-A/machine-1/state
factory/line-A/machine-2/temp
factory/line-A/machine-2/rpm
factory/line-B/machine-1/temp
factory/line-B/machine-1/rpm
factory/line-B/machine-2/temp
2 Linien Ă 2 Maschinen Ă 3 Sensoren = 12 Topics
factory/line-A/# â alles aus Linie Afactory/+/+/temp â nur Temperaturenfactory/+/machine-1/# â beide Linien, nur Maschine 1factory/# â alles fĂŒr die Ăbersichtfactory/# oder factory/+/+/temp picken automatisch alles Neue mit auf.
Ihr habt einen Sensor, der Bewegungsalarme im Hauseingang sendet. Welcher QoS-Level passt?
Eine Monitoring-App will alle Temperatur-Werte aus allen RĂ€umen im Haus empfangen. Welches Subscribe-Topic ist korrekt?
home/livingroom/temperaturehome/+/temperaturehome/#+/+/temperaturehome/+/temperaturehome/# matcht alles â auch TĂŒrsensoren, Licht, etc. Zu breit. Warum nicht D? Es matcht auch factory/line/temperature â verlĂ€sst das Haus. B ist prĂ€zise: nur Temperatur, nur im Haus, in beliebigen RĂ€umen.
Eine IoT-Wetterstation publiziert alle 60s ihre Temperatur. Eine Dashboard-App soll (1) sofort beim Start den aktuellen Wert sehen und (2) sofort wissen, wenn die Station ausfÀllt. Welche zwei MQTT-Features braucht ihr?
home/wz/temp). Wildcards: + (eine Ebene), # (alles drunter, nur am Ende).mosquitto_pub/mosquitto_sub im Terminal, paho-mqtt in Python.Im Ăbung: Pub/Sub-System mit mosquitto + Python â Sensor zu App.
Prof. Dr. Alexandra Mikityuk
HTW Berlin · BĂŒro Raum 308
Probiert test.mosquitto.org aus â kostet nichts und lĂ€uft sofort!
© 2026 HTW Berlin · Verteilte Systeme