Fondamentaux MQTT

Topics $SYS MQTT : ce que les topics système du broker vous apprennent

Un guide pratique de l'arborescence $SYS : son origine, pourquoi les wildcards l'ignorent, ce que les brokers de type Mosquitto y publient et comment suivre l'état de connexion des clients sur ConnectMQ.

Illustration des topics SYS MQTT partant d'un broker vers des statistiques de connexions, de clients et de messages
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Les topics SYS MQTT constituent la branche $SYS/... de l'arborescence de topics, dans laquelle un broker publie des informations sur lui-même plutôt que des données applicatives. Dans cet article, vous découvrirez l'origine de cette convention, pourquoi un simple abonnement # ne les affiche jamais, ce qu'un broker type y expose et comment utiliser l'unique topic système publié par ConnectMQ pour suivre l'état de connexion des clients.

Que sont les topics SYS MQTT ?

La spécification MQTT réserve les topics commençant par $ à un usage propre au broker. Les clients ne sont pas censés y publier de données applicatives, et la spécification laisse entièrement leur contenu à l'implémentation. Au fil des années, $SYS/ est devenu le préfixe de fait pour la télémétrie du broker : temps de fonctionnement, version, nombre de clients connectés, compteurs de messages et d'octets, et autres données de gestion similaires.

Le mot important est « de fait ». Il n'existe ni liste standard de topics $SYS, ni format de payload standard, ni garantie qu'un broker donné en publie un seul. Mosquitto a popularisé une vaste arborescence, d'autres brokers en publient un sous-ensemble ou une organisation différente, et de nombreux brokers MQTT managés en remplacent l'essentiel par des tableaux de bord et des API. Considérez chaque topic $SYS comme un détail d'implémentation du broker précis auquel vous êtes connecté.

Pourquoi un abonnement # ne les affiche pas

Cela surprend presque tout le monde la première fois. Si vous vous abonnez à #, vous recevez tous les messages applicatifs du broker, mais rien de $SYS. C'est voulu. La spécification MQTT sur mqtt.org indique qu'un filtre de topic commençant par un wildcard (# ou +) ne doit pas correspondre aux noms de topic commençant par $.

Cette règle protège les abonnés « fourre-tout » ordinaires contre un déluge de statistiques du broker, et évite que les outils qui répliquent # ne republient accidentellement des données système. Pour lire les topics système, vous devez nommer explicitement le préfixe $SYS :

#                  -> application topics only, never $SYS
$SYS/#             -> everything under $SYS (if the broker allows it)
$SYS/broker/+/+    -> a specific depth under $SYS/broker
+/broker/uptime    -> does NOT match $SYS/broker/uptime

Le même raisonnement s'applique aux règles des wildcards pour les topics MQTT en général : les wildcards fonctionnent niveau par niveau, et le niveau initial $ est tout simplement exclu de la correspondance par wildcard en première position.

Une arborescence $SYS type (exemple Mosquitto)

Mosquitto est la référence la plus courante : c'est donc un bon moyen de voir ce que peuvent contenir les topics système. Avec la configuration par défaut, il publie un instantané de ses compteurs toutes les quelques secondes. L'intervalle se règle dans mosquitto.conf :

# mosquitto.conf
# Publier les mises à jour $SYS toutes les 10 secondes (0 désactive les mises à jour périodiques)
sys_interval 10

Une sélection des topics que vous verrez sur une instance Mosquitto locale :

Topic Signification
$SYS/broker/version Chaîne de version du broker
$SYS/broker/uptime Secondes écoulées depuis le démarrage du broker
$SYS/broker/clients/connected Clients actuellement connectés
$SYS/broker/clients/disconnected Sessions persistantes dont le client est hors ligne
$SYS/broker/messages/received Total des messages reçus depuis le démarrage
$SYS/broker/messages/sent Total des messages envoyés depuis le démarrage
$SYS/broker/subscriptions/count Abonnements actifs
$SYS/broker/retained messages/count Retained messages conservés
$SYS/broker/load/messages/received/1min Moyenne glissante des messages reçus
$SYS/broker/bytes/received Total des octets reçus

Pour les observer sur votre propre broker Mosquitto, mettez le topic entre guillemets afin que votre shell n'interprète pas $SYS :

mosquitto_sub -h localhost -p 1883 -i sys-watcher-01 -t '$SYS/#' -v

La plupart des valeurs sont publiées sous forme de retained messages : un nouvel abonné reçoit donc immédiatement le dernier instantané au lieu d'attendre le prochain intervalle. Les compteurs sont remis à zéro au redémarrage du broker, ce qui compte si vous en faites des graphiques : une chute à zéro signifie un redémarrage, pas une heure calme.

Pièges courants avec les données $SYS

  • Supposer la portabilité. Un tableau de bord construit sur les topics $SYS de Mosquitto casse dès que vous passez à un autre broker. Gardez la logique d'analyse à un seul endroit.
  • Oublier le shell. En bash, "$SYS/#" entre guillemets doubles remplace $SYS par une variable vide, et vous vous abonnez à /#. Utilisez des guillemets simples.
  • L'exposer publiquement. Sur un broker auto-hébergé, les topics système révèlent le nombre de clients et les numéros de version. Restreignez-les avec les règles d'autorisation de votre broker s'il est accessible depuis Internet.
  • Interroger trop souvent. Un sys_interval très court ajoute du trafic pour peu de valeur. Dix à soixante secondes suffisent largement pour des graphiques d'exploitation.

Les topics SYS MQTT sur un broker managé

Sur un broker MQTT managé, vous n'avez généralement pas besoin d'une vaste arborescence $SYS, car l'opérateur collecte déjà les métriques du broker et vous les présente. C'est l'approche de ConnectMQ. Les informations au niveau du broker, comme les connexions et le trafic, sont présentées dans le tableau de bord du portail, et l'explorateur de topics en direct vous montre quels topics sont actifs : inutile donc d'analyser des compteurs issus de topics système.

Il publie exactement un topic système :

$SYS/broker/connection/{clientId}/state

Ce topic indique l'état de connexion d'un client ID précis. C'est la donnée $SYS dont le code applicatif a réellement besoin : « l'appareil X est-il en ligne en ce moment ? » Tout le reste, comme le nombre de clients et les débits de messages, relève de la supervision plutôt que de votre flux de données MQTT.

Suivre l'état de connexion d'un client

L'exemple ci-dessous utilise paho-mqtt 2.x en Python pour s'abonner au topic d'état d'un appareil sur votre broker privé. Remplacez les valeurs génériques par les identifiants générés dans le portail, et définissez DEVICE_ID avec le client ID de l'appareil à surveiller.

import ssl
import paho.mqtt.client as mqtt

BROKER = "YOUR_BROKER_HOST"      # affiché dans le portail
PORT = 8883
DEVICE_ID = "YOUR_DEVICE_CLIENT_ID"
STATE_TOPIC = f"$SYS/broker/connection/{DEVICE_ID}/state"

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print(f"Connect failed: {reason_code}")
        return
    print("Connected, subscribing to", STATE_TOPIC)
    client.subscribe(STATE_TOPIC, qos=1)

def on_subscribe(client, userdata, mid, reason_code_list, properties):
    for rc in reason_code_list:
        print("SUBACK:", rc)

def on_message(client, userdata, msg):
    print(f"{msg.topic} -> {msg.payload.decode(errors='replace')}")

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id="YOUR_CLIENT_ID",
    protocol=mqtt.MQTTv5,
)
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set(cert_reqs=ssl.CERT_REQUIRED)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message

client.connect(BROKER, PORT, keepalive=60)
client.loop_forever()

Lancez-le, puis éteignez et rallumez l'appareil ou arrêtez son client. Vous verrez le topic d'état changer à mesure que l'appareil se déconnecte et se reconnecte. Avant d'écrire votre logique d'analyse, examinez le payload réel dans le client MQTT intégré au navigateur du portail, afin que votre code corresponde à ce que le broker envoie et non à ce que vous supposez.

État $SYS ou Last Will

Vous suivez peut-être déjà la présence avec un message Last Will and Testament. Les deux approches se complètent :

Approche Qui publie Point fort Limite
Last Will plus message « online » retenu L'appareil, et le broker en son nom Fonctionne sur n'importe quel broker ; le topic et le payload vous appartiennent L'appareil doit être correctement configuré ; un client mal configuré ne signale jamais rien
$SYS/broker/connection/{clientId}/state Le broker Aucun code côté appareil ; reflète ce que le broker voit réellement Organisation des topics propre au broker

Un modèle sensé consiste à garder le Last Will pour les consommateurs applicatifs qui connaissent déjà votre arborescence de topics, et à utiliser le topic d'état du broker pour les outils d'exploitation et pour vérifier le bon comportement des appareils sans Will. Le guide sur le statut en ligne des appareils MQTT détaille le modèle basé sur le Will.

Liste de vérification de la supervision sans grande arborescence $SYS

Si vous venez d'un broker auto-hébergé dont les graphiques Grafana étaient alimentés par $SYS, voici comment couvrir les mêmes besoins sur un broker MQTT managé :

  1. Nombre de connexions et trafic. Utilisez le tableau de bord du broker dans le portail plutôt que $SYS/broker/clients/connected.
  2. Topics actifs. Utilisez l'explorateur de topics en direct plutôt qu'un abonnement à # depuis un ordinateur portable.
  3. Présence par appareil. Abonnez-vous à $SYS/broker/connection/{clientId}/state pour les client ID qui vous intéressent, ou utilisez un Last Will.
  4. Conditions de seuil sur les données. Configurez des règles d'alerte dans le portail pour des valeurs comme la température ou la pression, et consultez le journal des alertes.
  5. Historique des métriques à long terme. Exécutez votre propre abonné (Telegraf, un petit service Python ou Node-RED) qui écrit les données nécessaires dans votre base de séries temporelles.
  6. Suivi des quotas. Surveillez le reason code MQTT 5 0x97 (quota exceeded) dans les journaux des clients ; il indique qu'une limite de l'offre a été atteinte.

Tester sur le broker public

Si vous voulez seulement expérimenter la structure des topics, le serveur MQTT public gratuit broker.connectmq.com accepte les connexions anonymes avec n'importe quel client ID unique non vide. Gardez à l'esprit que l'espace public est lisible par tous : utilisez un préfixe unique et n'envoyez jamais de données sensibles.

# Terminal 1 : s'abonner à votre propre préfixe de démonstration
mosquitto_sub -h broker.connectmq.com -p 1883 -i sys-demo-sub-7f3a \
  -t 'connectmq/demo/7f3a/#' -v

# Terminal 2 : publier un message de test
mosquitto_pub -h broker.connectmq.com -p 1883 -i sys-demo-pub-7f3a \
  -t 'connectmq/demo/7f3a/hello' -m 'hi'

Remarquez que l'abonnement # du terminal 1 voit votre message, mais rien sous $SYS, exactement comme l'exige la spécification. Pour une vue d'ensemble de la manière dont les topics, les abonnements et le broker s'articulent, le tutoriel MQTT est une bonne lecture suivante, et les conventions de nommage des topics MQTT expliquent comment garder votre propre arborescence aussi ordonnée que l'arborescence système d'un broker.

Démarrer avec ConnectMQ

Vous voulez les métriques du broker sans analyser des compteurs $SYS ? Créez un broker Serverless gratuit sur app.connectmq.com, sans carte bancaire. En quelques minutes, vous obtenez des identifiants générés, un tableau de bord, un explorateur de topics en direct et le topic $SYS/broker/connection/{clientId}/state pour la présence de chaque appareil.

Questions fréquentes

Pourquoi l'abonnement à # n'affiche-t-il pas les messages $SYS ?

La spécification MQTT indique que les filtres de topic commençant par un wildcard ne doivent pas correspondre aux topics commençant par $. Abonnez-vous explicitement à $SYS/# si votre broker publie des topics système et vous autorise à les lire.

Les topics SYS MQTT sont-ils standardisés ?

Non. Seule la réservation des topics préfixés par $ est standardisée. Les noms de topics, les payloads et les intervalles de mise à jour diffèrent d'un broker à l'autre : le code qui les lit est donc propre à chaque broker.

Quel topic $SYS ConnectMQ publie-t-il ?

ConnectMQ publie $SYS/broker/connection/{clientId}/state, qui indique l'état de connexion d'un client. Les métriques du broker, comme les connexions et le trafic, sont affichées dans le tableau de bord du portail.

Puis-je publier mes propres messages sur les topics $SYS ?

C'est déconseillé. Le préfixe $ est réservé au broker, et la plupart des brokers rejettent ou ignorent les publications des clients à cet endroit. Placez vos propres données de statut dans l'arborescence de topics de votre application.

Articles liés

Qui a inventé MQTT ? L'histoire, des oléoducs à l'IoT

MQTT a été inventé en 1999 par Andy Stanford-Clark (IBM) et Arlen Nipper (Arcom) pour surveiller des oléoducs par satellite. Suivez son parcours vers l'open source, OASIS, l'ISO et les brokers MQTT managés d'aujourd'hui.

8 min de lecture

Pourquoi votre client MQTT se déconnecte sans cesse (et comment y remédier)

Les boucles de reconnexion sont l'un des problèmes MQTT les plus courants. Découvrez les cinq causes habituelles, des client ID en double aux timeouts de keep alive et aux paquets trop volumineux, et suivez une méthode de diagnostic qui identifie la vôtre.

9 min de lecture

Taille maximale d'un message MQTT : limites et stratégies pour les gros payloads

MQTT peut techniquement transporter un paquet de 256 Mo, mais les brokers, les bibliothèques clientes et les appareils imposent des limites bien plus basses. Découvrez où se trouvent les vraies limites, ce qui se passe quand on les dépasse et comment envoyer de gros payloads.

8 min de lecture

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.