MQTT-Grundlagen

MQTT Message Expiry Interval: Veraltete Befehle stoppen

In MQTT 5 kann ein Publisher festlegen, wie lange eine Nachricht gültig bleibt. Erfahren Sie, wie das Message Expiry Interval mit persistenten Sessions und Retained Messages zusammenspielt und wie Sie verhindern, dass spät verbundene Geräte veraltete Befehle ausführen.

Uhr neben einem gepufferten Befehl, der nach Ablauf des MQTT Message Expiry Interval verworfen wird
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Das MQTT Message Expiry Interval ist eine MQTT-5-Property, die dem Broker mitteilt, wie viele Sekunden eine Nachricht gültig bleibt. Ist diese Zeit abgelaufen, verwirft der Broker die Nachricht, statt sie an einen Client auszuliefern, der sich zu spät wieder verbindet. In diesem Artikel erfahren Sie genau, wie Expiry funktioniert, sehen in einem Live-Test, wie ein veralteter Befehl verworfen wird, und erhalten eine Checkliste für die Wahl der Expiry-Werte in Ihrem eigenen System.

Das Problem: Befehle, die zu spät ankommen

Stellen Sie sich ein Gerät vor, das mit QoS 1 und einer persistenten Session abonniert hat. Ein Bediener sendet „Tor öffnen“, während das Gerät offline ist. Der Broker puffert den Befehl, weil die Session noch lebt. Zwei Stunden später verbindet sich das Gerät über eine wackelige Mobilfunkverbindung wieder, und der Broker liefert pflichtbewusst „Tor öffnen“ aus. Am Tor steht längst niemand mehr.

In der Fertigung ist das Muster dasselbe: Ein MES schickt einen Auftrags- oder Rezeptwechsel an eine Linie, deren Gateway gerade neu startet. Kommt der Befehl erst nach Schichtende an, passt er nicht mehr zum aktuellen Produktionsstand.

Vor MQTT 5 gab es keinen Weg auf Protokollebene, das zu verhindern. Entwickler fügten Zeitstempel in Payloads ein und hofften, dass jedes Gerät sie prüft. MQTT 5 hat die Lösung mit dem Message Expiry Interval, einer Property des PUBLISH-Pakets, ins Protokoll verlagert. Es ist eine der praktischsten MQTT-5-Funktionen für alle, die physische Anlagen steuern.

So funktioniert das MQTT Message Expiry Interval

Der Publisher setzt die Property in Sekunden als Vier-Byte-Ganzzahl. Der Broker wendet dann folgende Regeln an:

  1. Beim Eintreffen der Nachricht notiert der Broker die Zeit.
  2. Wird die Nachricht für einen Offline-Subscriber mit persistenter Session gepuffert und läuft das Intervall vor der Zustellung ab, verwirft der Broker sie.
  3. Liefert der Broker die Nachricht aus, schreibt er die Property auf die verbleibende Zeit um. Eine mit 60 Sekunden publizierte und 45 Sekunden später zugestellte Nachricht kommt mit einem Intervall von 15 an.
  4. Ist die Nachricht retained, läuft auch die gespeicherte Kopie ab. Nach dem Intervall erhalten neue Subscriber sie nicht mehr.
  5. Fehlt die Property, läuft die Nachricht nie ab – das ist das Verhalten von MQTT 3.1.1.

Die vierte Regel macht Expiry über Befehle hinaus nützlich. Ein gespeichertes Banner „Wartungsmodus aktiv“ kann so eingestellt werden, dass es von selbst abläuft, damit ein vergessenes Flag nicht wochenlang bestehen bleibt.

Nachrichtentyp Empfohlenes Expiry Begründung
Aktorbefehl (öffnen, starten, stoppen) 5 bis 60 s Nur gültig, solange ein Bediener zusieht
Konfigurations-Push Stunden bis Tage Weiterhin nützlich, wenn sich ein Gerät später verbindet
Telemetrie an einen persistenten Konsumenten Minuten Alte Messwerte verlieren an Wert, können aber Lücken füllen
Gespeicherter temporärer Zustand Dauer des Zustands Räumt sich automatisch auf
Alarmbenachrichtigung Bis kein Handeln mehr möglich ist Fluten veralteter Alarme vermeiden

Warum Expiry erst mit persistenten Sessions zählt

Expiry betrifft nur Nachrichten, die irgendwo warten. Bei einer Clean Session ohne gespeicherten Zustand verpasst ein getrennter Subscriber Nachrichten einfach, es gibt also nichts, was ablaufen könnte. Expiry wirkt an zwei Stellen:

  • Session-Queues. Bei einem Client, der sich mit Clean Start false und einem Session Expiry Interval größer null verbindet, werden QoS-1- und QoS-2-Nachrichten gepuffert, solange er offline ist. Siehe MQTT Session Expiry Interval, wo erklärt wird, wie diese Queue entsteht.
  • Retained-Speicher. Eine Retained Message mit Expiry wird nach dem Intervall entfernt.

Beachten Sie den Unterschied zwischen den beiden Expiry-Einstellungen: Session Expiry steuert, wie lange sich der Broker an einen Client erinnert; Message Expiry steuert, wie lange sich die Zustellung einer einzelnen Nachricht lohnt. In der Regel wollen Sie beides.

Message Expiry auf einem Live-Broker testen

Wir nutzen den öffentlichen MQTT-Broker unter broker.connectmq.com, der MQTT 5 und Sessions bis zu 30 Minuten unterstützt. Verwenden Sie Ihr eigenes Topic-Präfix, und senden Sie dort nur Testdaten: Der Broker ist für Tests und Prototypen gedacht, nicht für Produktionsdaten.

Schritt 1: Persistente Session anlegen. Verbinden Sie sich einmal mit deaktiviertem Clean Start (-c), 600 Sekunden Session Expiry (-x 600) und QoS 1, und beenden Sie dann mit Strg+C:

mosquitto_sub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-dev-m4t9 \
  -c -x 600 -q 1 -t connectmq/demo/m4t9/gate/cmd -v

Schritt 2: Publizieren Sie, während der Subscriber offline ist, einen Befehl, der in 10 Sekunden abläuft, und einen, der 5 Minuten gilt:

mosquitto_pub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-op-m4t9 -q 1 \
  -t connectmq/demo/m4t9/gate/cmd -m 'open (10s)' \
  -D publish message-expiry-interval 10

mosquitto_pub -V mqttv5 -h broker.connectmq.com -p 1883 -i exp-op-m4t9 -q 1 \
  -t connectmq/demo/m4t9/gate/cmd -m 'report-status (300s)' \
  -D publish message-expiry-interval 300

Schritt 3: Warten Sie mindestens 20 Sekunden und verbinden Sie sich dann mit exakt demselben Befehl wie in Schritt 1 erneut. Nur report-status (300s) kommt an. Der Öffnen-Befehl ist in der Queue abgelaufen und wurde nie zugestellt. Führen Sie Schritt 2 und 3 noch einmal zügig innerhalb von 10 Sekunden aus, und beide Nachrichten kommen an.

Expiry in Python und Node.js setzen

In paho-mqtt 2.x hängen Sie dem Publish ein Properties-Objekt an. Der Client muss MQTT 5 verwenden:

import json
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id=f"op-{uuid.uuid4().hex[:8]}",
    protocol=mqtt.MQTTv5,
)
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_start()

props = Properties(PacketTypes.PUBLISH)
props.MessageExpiryInterval = 30  # Sekunden

cmd = {"action": "open", "issuedBy": "operator-3"}
info = client.publish("connectmq/demo/m4t9/gate/cmd", json.dumps(cmd), qos=1, properties=props)
info.wait_for_publish()

client.loop_stop()
client.disconnect()

Auf der Empfängerseite enthält msg.properties den Wert MessageExpiryInterval mit den verbleibenden Sekunden, den ein Gerät protokollieren oder nutzen kann, um Befehle abzulehnen, deren Zeit fast abgelaufen ist.

Bei MQTT.js v5 steht die Property in den Publish-Optionen:

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "op-" + Math.random().toString(16).slice(2, 10),
  protocolVersion: 5,
});

client.on("connect", () => {
  client.publish(
    "connectmq/demo/m4t9/gate/cmd",
    JSON.stringify({ action: "close" }),
    { qos: 1, properties: { messageExpiryInterval: 30 } },
    (err) => {
      if (err) console.error(err);
      client.end();
    }
  );
});

Fallstricke und Fehlersuche

Expiry wird komplett ignoriert. Prüfen Sie, ob sowohl die Verbindung des Publishers als auch die zum Broker MQTT 5 nutzen. Ein 3.1.1-Client kann die Property nicht senden, und ein 3.1.1-Subscriber erhält die Nachricht ohne sie.

Die Nachricht kommt trotzdem zu spät an. Expiry stoppt die Zustellung aus der Queue des Brokers. Es hilft nicht, wenn die Nachricht bereits im eigenen Puffer des Geräts oder in einem Gateway dazwischen liegt. Geräte, die Befehle ausführen, sollten bei sicherheitsrelevanten Abläufen weiterhin einen Zeitstempel im Payload mit ihrer Uhr abgleichen.

Befehle laufen zu schnell ab. Denken Sie an Netzwerk- und Queue-Latenzen im Broker. Ein Expiry von 1 oder 2 Sekunden kann auf langsamen Verbindungen legitime Befehle verwerfen.

Retained Message ist verschwunden. Hat jemand den Retained-Wert mit Expiry publiziert, verschwindet er nach Ablauf des Intervalls. Das ist oft gewollt; prüfen Sie den Publisher, bevor Sie Datenverlust vermuten. Grundlagen zu Retained Messages finden Sie unter MQTT Retained Messages.

Expiry versus QoS. QoS steuert, ob eine Nachricht zugestellt wird; Expiry steuert, ob sich die Zustellung noch lohnt. Eine QoS-1-Nachricht mit Expiry kann völlig legitim nie ankommen.

Expiry mit weiteren Schutzmaßnahmen kombinieren

Message Expiry ist eine Verteidigungsschicht, nicht das ganze Design. Bei Befehlen, die physische Anlagen bewegen, kombiniert ein robustes Setup meist mehrere Mechanismen:

  1. Expiry für jeden Befehl, damit der Broker veraltete Befehle aus den Queues entfernt.
  2. Eine Befehls-ID und ein Ausgabezeitstempel im Payload, damit das Gerät alles ablehnen kann, was älter als sein eigener Schwellenwert ist – selbst wenn ein Gateway es gepuffert hat.
  3. Kein Retain-Flag bei Befehlen, damit ein Neustart nie eine alte Anweisung erneut abspielt.
  4. Ein Bestätigungs-Topic, auf dem das Gerät meldet, ob es den Befehl ausgeführt oder abgelehnt hat, idealerweise mit dem MQTT-Request-Response-Muster.
  5. Verriegelungen auf dem Gerät für alles Sicherheitsrelevante. Das Netzwerk sollte nie das Einzige sein, was eine unsichere Aktion verhindert. In Anlagen bleibt diese Logik in der SPS und der Sicherheitstechnik; MQTT übermittelt nur die Anforderung.

Arbeiten Sie mit einem Unified Namespace (UNS) nach ISA-95, legen Sie Befehls-Topics direkt am Knoten der Anlage ab, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/cmd, und definieren Sie die Expiry-Richtlinie pro Befehlstyp zentral. So gilt für jede Zelle dieselbe Regel, unabhängig davon, welche Anwendung den Befehl sendet.

Betrachten Sie Expiry als das Werkzeug, das Queues sauber hält und verspätete Zustellung selten macht, während die Prüfungen auf dem Gerät eine verspätete Ausführung unmöglich machen.

Message Expiry auf ConnectMQ

ConnectMQ unterstützt MQTT 5.0 mit Message Expiry, Session Expiry, Response Topic und den übrigen MQTT-5-Properties auf seinen MQTT-5.0-Verbindungen. Verbinden Sie im Produktivbetrieb Ihre Bedienwerkzeuge und Geräte mit Zugangsdaten aus dem Portal über TLS auf Port 8883 und setzen Sie Expiry als Richtlinie auf jedem Befehls-Topic. Ein verwalteter MQTT-Broker übernimmt den Betrieb von Session-Speicher und Queues, sodass Ihr Team nur noch sinnvolle Expiry-Werte wählen muss. Das MQTT-Tutorial behandelt die übrigen Grundlagen.

Starten Sie mit ConnectMQ

Erstellen Sie kostenlos einen Broker unter app.connectmq.com im Serverless-Plan, ganz ohne Kreditkarte. Verbinden Sie sich mit MQTT 5, versehen Sie Ihren ersten Befehl mit einem Expiry und testen Sie ihn gegen ein Gerät, das sich verspätet wieder verbindet. Mit einem Cloud-MQTT-Broker müssen Sie beim Experimentieren keine Server pflegen.

Häufig gestellte Fragen

Welche Einheit verwendet das Message Expiry Interval?

Sekunden, gespeichert als vorzeichenlose Vier-Byte-Ganzzahl. Ist die Property nicht gesetzt, läuft die Nachricht nicht ab.

Sieht der Subscriber den ursprünglichen Expiry-Wert?

Nein. Der Broker sendet die verbleibende Zeit, sodass ein Subscriber erkennen kann, wie viel Gültigkeit beim Eintreffen der Nachricht noch übrig ist.

Funktioniert Message Expiry mit MQTT 3.1.1?

Nein. Es ist eine MQTT-5-Property. Mit MQTT 3.1.1 brauchen Sie einen Zeitstempel im Payload, den der Empfänger selbst prüft.

Können Retained Messages ablaufen?

Ja. Eine mit Expiry Interval publizierte Retained Message wird nach Ablauf des Intervalls aus dem Retained-Speicher entfernt.

Verwandte Artikel

Wer hat MQTT erfunden? Die Geschichte von Ölpipelines bis zum IoT

MQTT wurde 1999 von Andy Stanford-Clark (IBM) und Arlen Nipper (Arcom) erfunden, um Ölpipelines per Satellit zu überwachen. Verfolgen Sie den Weg zu Open Source, OASIS, ISO und den heutigen verwalteten MQTT-Brokern in der Cloud.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.