Externes Uptime-Monitoring beantwortet eine einzige Frage: Könnte sich ein Gerät außerhalb deines Netzwerks gerade jetzt mit dem Broker verbinden und eine Nachricht austauschen? Interne Metriken können das nicht beantworten. Sie sehen keine DNS-Fehler, abgelaufenen Zertifikate, defekten Load Balancer oder Firewall-Änderungen. Das sieht nur eine Probe, die sich wie ein Client verhält und von außen läuft.
Dieser Guide baut diese Probe, plant ihre Ausführung, leitet Alerts an Slack oder PagerDuty weiter und zeigt die SLO-Rechnung, mit der du Prüfintervall und Alert-Schwelle festlegst.
Was "verfügbar" bei einem MQTT-Broker bedeutet
"Der Port ist offen" ist eine schwache Definition. Ein Broker ist nur nützlich, wenn alle diese Schichten funktionieren:
| Schicht | Prüfung | Typischer Fehler, den sie findet |
|---|---|---|
| DNS | Hostname wird aufgelöst | Abgelaufene Domain, falscher Eintrag nach einer Migration |
| TCP | Port 8883 nimmt Verbindungen an | Firewall, Security Group, Broker-Prozess gestoppt |
| TLS | Handshake klappt, Zertifikat noch N Tage gültig | Abgelaufenes oder unpassendes Zertifikat |
| MQTT CONNECT | CONNACK mit Erfolgscode | Auth-Backend down, Zugangsdaten rotiert, Verbindungslimit erreicht |
| Round Trip | Gepublishte Nachricht kommt innerhalb des Timeouts an | Routing kaputt, Cluster gespalten, Überlast |
Prüfe jede Schicht einzeln und melde, welche fehlgeschlagen ist. "TLS fehlgeschlagen, Zertifikat abgelaufen" behebst du in fünf Minuten. "Probe fehlgeschlagen" startet eine halbstündige Suche. Für einmalige manuelle Checks siehe MQTT-Broker-Status prüfen und testen, ob ein MQTT-Port offen ist.
Eine minimale Probe mit den Mosquitto-Clients
Wenn du mosquitto_pub und mosquitto_sub schon hast, passt eine Shell-Probe in ein Dutzend Zeilen:
#!/usr/bin/env bash
set -u
HOST=broker.connectmq.com; PORT=8883
TOPIC="testmqtt/uptime/$(hostname)-$$"
MSG="ping-$(date +%s)"
OUT=$(mktemp)
mosquitto_sub -h "$HOST" -p "$PORT" --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t "$TOPIC" -q 1 -C 1 -W 10 > "$OUT" &
SUB=$!
sleep 1
mosquitto_pub -h "$HOST" -p "$PORT" --capath /etc/ssl/certs \
-u "$MQTT_USER" -P "$MQTT_PASS" -t "$TOPIC" -q 1 -m "$MSG"
wait $SUB
if grep -qx "$MSG" "$OUT"; then echo "OK"; rm -f "$OUT"; exit 0
else echo "FAIL: no round trip within 10 s"; rm -f "$OUT"; exit 1; fi-C 1 beendet den Subscriber nach einer Nachricht, und -W 10 lässt ihn nach zehn Sekunden aufgeben. Der Exit-Code ist alles, was ein Scheduler oder Heartbeat-Dienst braucht.
Eine Probe mit Schichten in Python
Diese Version (paho-mqtt 2.x) prüft jede Schicht, misst die Zeit, meldet die verbleibenden Tage bis zum Zertifikatsablauf und gibt eine JSON-Zeile aus, die sich leicht in Logs übernehmen lässt:
import json, os, socket, ssl, sys, threading, time, uuid
import paho.mqtt.client as mqtt
HOST, PORT, TIMEOUT = "broker.connectmq.com", 8883, 10
result = {"host": HOST, "ts": int(time.time())}
def fail(stage, detail):
result.update(ok=False, stage=stage, detail=str(detail))
print(json.dumps(result)); sys.exit(1)
t = time.perf_counter()
try:
socket.getaddrinfo(HOST, PORT)
except OSError as e:
fail("dns", e)
try:
ctx = ssl.create_default_context()
with socket.create_connection((HOST, PORT), timeout=TIMEOUT) as raw:
with ctx.wrap_socket(raw, server_hostname=HOST) as tls:
not_after = ssl.cert_time_to_seconds(tls.getpeercert()["notAfter"])
except ssl.SSLError as e:
fail("tls", e)
except OSError as e:
fail("tcp", e)
result["cert_days_left"] = int((not_after - time.time()) // 86400)
result["tls_ms"] = round((time.perf_counter() - t) * 1000)
topic = f"testmqtt/uptime/{uuid.uuid4().hex[:8]}"
connack, got = {}, threading.Event()
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"testmqtt-uptime-{uuid.uuid4().hex[:6]}")
c.username_pw_set(os.getenv("MQTT_USER"), os.getenv("MQTT_PASS"))
c.tls_set_context(ctx)
c.on_connect = lambda cl, ud, fl, rc, pr: (connack.update(rc=rc),
None if rc.is_failure else cl.subscribe(topic, qos=1))
c.on_subscribe = lambda cl, ud, mid, rcs, pr: cl.publish(topic, "ping", qos=1)
c.on_message = lambda cl, ud, msg: got.set()
t = time.perf_counter()
try:
c.connect(HOST, PORT, keepalive=15)
except OSError as e:
fail("connect", e)
c.loop_start()
ok = got.wait(TIMEOUT)
c.disconnect(); c.loop_stop()
if "rc" not in connack:
fail("connect", "no CONNACK")
if connack["rc"].is_failure:
fail("connect", connack["rc"])
if not ok:
fail("roundtrip", f"no message within {TIMEOUT} s")
result.update(ok=True, roundtrip_ms=round((time.perf_counter() - t) * 1000))
print(json.dumps(result))
sys.exit(2 if result["cert_days_left"] < 14 else 0)Exit-Code 0 bedeutet gesund, 1 bedeutet ausgefallen (das Feld stage sagt, wo), und 2 bedeutet erreichbar, aber das Zertifikat läuft in weniger als zwei Wochen ab. Letzteres ist eine Warnung, kein Bereitschaftsalarm. Scheitert die Stufe connect, zeigt der Reason Code (zum Beispiel Not authorized), ob es an den Zugangsdaten oder an einer ACL liegt. Schlag ihn im Reason-Code-Tool oder unter MQTT-Verbindungsfehler nach.
Die Probe zeitgesteuert ausführen
- cron oder ein systemd-Timer auf einer kleinen VM außerhalb des Broker-Netzwerks:
* * * * * /opt/probe/mqtt_uptime_probe.py >> /var/log/mqtt-probe.log 2>&1. Das ist einfach und läuft jede Minute. - Mehrere Standorte. Lass dieselbe Probe aus zwei oder drei Regionen oder bei verschiedenen Anbietern laufen. Alarmiere, wenn die Mehrheit fehlschlägt. Fällt nur ein Standort aus, liegt es meist an dessen Netzwerk.
- GitHub Actions
scheduletaugt für unkritische Checks, aber das Mindestintervall beträgt fünf Minuten, und Läufe können verspätet starten. Für Bereitschaftsalarme ist das nicht geeignet. - Uptime Kuma (selbst gehostet) bringt einen MQTT-Monitortyp mit und passt gut, wenn du eine Oberfläche bevorzugst.
Auch das, was die Probe ausführt, kann ausfallen. Nutze einen Heartbeat (Dead Man's Switch): Nach jedem erfolgreichen Lauf pingt die Probe eine URL bei einem Heartbeat-Dienst wie Healthchecks.io oder einem Push-Monitor von Uptime Kuma an. Bleiben die Pings aus, ist entweder der Broker oder der Probe-Host down, und in beiden Fällen bekommst du einen Alert:
* * * * * /opt/probe/mqtt-probe.sh && curl -fsS -m 10 --retry 3 "$HEARTBEAT_URL" > /dev/nullAlert-Kanäle
Schick Alerts dorthin, wo sie tatsächlich jemand sieht, und erst bei ausreichender Evidenz. Eine gängige Regel lautet drei aufeinanderfolgende Fehlschläge von mindestens zwei Standorten, plus eine Entwarnung, sobald es wieder läuft.
curl -fsS -X POST -H 'Content-Type: application/json' \
-d '{"text":":red_circle: MQTT probe failed at stage tls (broker.connectmq.com:8883)"}' \
"$SLACK_WEBHOOK_URL"curl -fsS -X POST https://events.pagerduty.com/v2/enqueue \
-H 'Content-Type: application/json' \
-d '{"routing_key":"'"$PD_ROUTING_KEY"'","event_action":"trigger",
"dedup_key":"mqtt-probe-broker",
"payload":{"summary":"MQTT round trip failing","source":"mqtt-probe","severity":"critical"}}'Sende dieselbe Anfrage mit "event_action":"resolve" und derselben dedup_key, um den Incident automatisch zu schließen. Warnungen zum Zertifikatsablauf gehören in Slack oder in die E-Mail. Darum muss sich jemand diese Woche kümmern, nicht um 3 Uhr nachts. Wenn du Prometheus schon betreibst, exportiere die Probe als Metriken und alarmiere dort. Siehe MQTT mit Prometheus und Grafana überwachen.
SLO-Rechnung
Ein Verfügbarkeitsziel ergibt nur zusammen mit seinem Ausfallbudget Sinn:
| Verfügbarkeit | Ausfallzeit pro 30 Tage | Ausfallzeit pro Jahr |
|---|---|---|
| 99 % | 7 h 12 min | 3,65 Tage |
| 99,5 % | 3 h 36 min | 1,83 Tage |
| 99,9 % | 43,2 min | 8 h 46 min |
| 99,95 % | 21,6 min | 4 h 23 min |
| 99,99 % | 4,3 min | 52,6 min |
Miss sie als erfolgreiche Probes ÷ alle Probes. Eine Probe pro Minute ergibt in 30 Tagen 43.200 Messwerte, 99,9 % erlauben also 43 fehlgeschlagene Probes. Daraus folgen drei Dinge:
- Das Intervall begrenzt die Genauigkeit. Bei einer Probe pro Minute kann ein 20-Sekunden-Ausfall unbemerkt bleiben oder als ganze Minute zählen. Willst du 99,99 % messen, prüfe alle 10–15 Sekunden.
- Die Erkennungszeit frisst das Budget. Drei Fehlschläge im Minutentakt bedeuten rund drei Minuten, bis jemand alarmiert wird. Bei 99,9 % (43 Minuten) ist das in Ordnung, bei 99,99 % ist es fast das ganze Budget.
- Dein SLO ist nicht das SLA des Anbieters. Das SLA deckt den Broker ab. Deine Probe misst den gesamten Pfad, inklusive deines DNS, deiner Zertifikate und deines Netzwerks. Lies SLAs und Uptime von MQTT-Brokern, bevor du beides vergleichst.
Behalte das Error Budget im Blick: Sind zur Monatsmitte schon 30 deiner 43 Minuten verbraucht, friere riskante Änderungen am Broker ein, bis es sich erholt hat.
Den Alert-Pfad testen
Eine Probe, die nie fehlgeschlagen ist, ist nicht getestet. Bevor du dich auf sie verlässt:
- Setze ein falsches Passwort und prüfe, dass die Stufe
connectfehlschlägt und der Alert in Slack oder PagerDuty ankommt. - Richte
HOSTauf einen Namen, der sich nicht auflösen lässt, und prüfe aufstage: dns. - Stoppe den Cron-Job und prüfe, dass der Heartbeat-Dienst dich alarmiert.
- Prüfe von Hand, ob die Sicht der Probe der Realität entspricht: Verbinde dich mit dem Online-MQTT-Client und publishe auf das Probe-Topic, während die Probe läuft.
Externes Uptime-Monitoring besteht aus einem kleinen Skript, einem Scheduler und einem Heartbeat. Prüfe jede Schicht einzeln, alarmiere nur bei wiederholten Fehlschlägen von mehr als einem Standort, leite das Probe-Intervall aus deinem SLO ab und mach das Setup einmal absichtlich kaputt, um zu beweisen, dass die Alerts ankommen.
Häufig gestellte Fragen
Reicht es, zu prüfen, ob Port 1883 offen ist, um die MQTT-Uptime zu überwachen?
Nein. Ein Broker kann TCP-Verbindungen annehmen und trotzdem Logins ablehnen, an TLS scheitern oder keine Nachrichten routen. Ein echter Uptime-Check verbindet sich mit Zugangsdaten, abonniert, publisht eine Nachricht und bestätigt, dass sie innerhalb eines Timeouts ankommt.
Wie oft sollte eine MQTT-Uptime-Probe laufen?
Jede Minute ist ein guter Standard. Das Intervall begrenzt, wie genau du Verfügbarkeit messen kannst: Bei einem Check pro Minute bleiben Ausfälle unter einer Minute eventuell unbemerkt, und ein monatliches 99,99-%-Budget von rund vier Minuten ist aufgebraucht, bevor ein Alert nach drei Fehlschlägen auslöst.
Wie viel Ausfallzeit erlaubt 99,9 %?
Etwa 43 Minuten pro 30-Tage-Monat oder rund 8 Stunden 46 Minuten pro Jahr. 99,95 % erlauben etwa 22 Minuten pro Monat, 99,99 % etwa 4,3 Minuten.


