Managed MQTT Cloud

Architektur mandantenfähiger MQTT-Broker: Namespaces, Zugangsdaten und Kontingente

Ein praxisnaher Blick auf die Architektur mandantenfähiger MQTT-Broker: wie Mandanten durch Namespace, Identität und Ressourcenlimits getrennt werden, welche Kompromisse zählen und wie ConnectMQ sie umsetzt.

Architekturdiagramm eines mandantenfähigen MQTT-Brokers mit getrennten Mandanten-Namespaces, Zugangsdaten und Kontingentanzeigen auf einem geteilten Cluster
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

Ein mandantenfähiger MQTT-Broker bedient viele unabhängige Kunden oder Teams über eine gemeinsame Infrastruktur und hält dabei die Nachrichten, Identitäten und den Ressourcenverbrauch jedes Einzelnen getrennt. Dieser Artikel führt durch die Bausteine dieser Architektur, also Namespaces, Zugangsdaten und Kontingente, die Kompromisse zwischen ihnen und die Fragen, die Sie einem Anbieter stellen sollten. Am Ende haben Sie ein Denkmodell, mit dem Sie Ihre eigene Plattform entwerfen oder die eines anderen bewerten können.

Was Mandantenfähigkeit für einen MQTT-Broker bedeutet

Bei MQTT verbindet sich jeder Client mit einem Broker und veröffentlicht auf Topics oder abonniert sie. Ein einfacher Broker hat einen einzigen flachen Topic-Bereich: Jeder Client, der # abonnieren darf, sieht alles. Für eine einzelne Anwendung ist das in Ordnung, gefährlich wird es in dem Moment, in dem sich zwei Kunden denselben Server teilen.

Ein Mandant ist eine Isolationseinheit: ein Kunde, ein Geschäftsbereich, ein Werk, eine Umgebung wie Staging oder eine Produktlinie. Ein typisches Beispiel aus dem Maschinenbau ist ein Hersteller, der die Maschinendaten seiner Kunden für Fernwartung und Predictive Maintenance sammelt: Jeder Endkunde ist ein eigener Mandant und darf die Daten der anderen niemals sehen. Mandantenfähigkeit bedeutet, dass der Broker jeden Mandanten so behandelt, als hätte er einen eigenen privaten Broker, obwohl die Verbindungen auf denselben Prozessen und Maschinen landen. Dafür muss die Architektur für jede Verbindung und jede Nachricht drei Fragen beantworten:

  1. Zu welchem Mandanten gehört dieser Client? (Identität)
  2. Welche Topics darf dieser Client sehen und beschreiben? (Namespace)
  3. Wie viel der gemeinsamen Kapazität darf dieser Mandant verbrauchen? (Ressourcen)

Wenn Sie eine Auffrischung zu Brokern im Allgemeinen brauchen, lesen Sie zuerst, was ein MQTT-Broker leistet.

Baustein 1: Mandanten-Namespaces

Topic-Präfixe

Der einfachste Ansatz ist eine Konvention: Die Topics jedes Mandanten beginnen mit einem Präfix, etwa tenant-42/site-a/line-1/temperature. Der Broker oder eine vorgeschaltete Autorisierungsschicht muss dann durchsetzen, dass ein Client von Mandant 42 nur Topics unter tenant-42/ verwenden kann. Ohne Durchsetzung ist ein Präfix nur eine ordentliche Benennung, keine Isolation.

In Industrie-4.0-Projekten folgt unterhalb des Mandantenpräfixes meist ein Unified Namespace (UNS), dessen Struktur sich an der Equipment-Hierarchie nach ISA-95 (IEC 62264) orientiert: Enterprise → Site → Area → Line → Cell. Aus Präfix und Hierarchie entsteht ein Topic wie tenant-42/werk-stuttgart/montage/linie-1/zelle-3/temperatur. Jeder Mandant erhält so seinen eigenen, einheitlich aufgebauten UNS, und die Autorisierung muss nur die oberste Ebene absichern. Mehr dazu im Beitrag zu Sparkplug B und Unified Namespace.

Mountpoints und virtuelle Hosts

Manche Broker unterstützen Mountpoints oder ähnliche Mechanismen: Der Broker stellt jedem Topic, das ein Client verwendet, stillschweigend ein mandantenspezifisches Präfix voran. Der Client veröffentlicht auf sensors/temp, und der Broker speichert und routet es als tenant-42/sensors/temp. Clients können ein Topic außerhalb ihres Namespace gar nicht erst ausdrücken, und ein Abonnement auf # passt nur innerhalb des Bereichs des Mandanten. Das ist stärker als eine Konvention, weil es nicht auf korrektes Client-Verhalten angewiesen ist.

Getrennte logische Broker

Das stärkste logische Modell gibt jedem Mandanten eine eigene Broker-Instanz-Identität mit eigenen Zugangsdaten, eigenem Session-Speicher und eigenen Retained Messages, selbst wenn der darunterliegende Cluster geteilt wird. Ein Wildcard-Abonnement in einem Mandanten kann niemals ein Topic in einem anderen treffen, weil sie überhaupt keinen gemeinsamen Topic-Baum haben.

Baustein 2: Identität und Zugangsdaten

Isolation beginnt beim CONNECT. Ein robustes Design bindet jeden Satz Zugangsdaten an genau einen Mandanten und prüft ihn, bevor irgendeine Topic-Operation akzeptiert wird.

  • Zugangsdaten pro Mandant. Benutzernamen und Passwörter, Tokens oder Client-Zertifikate werden pro Mandant ausgegeben, idealerweise pro Gerät.
  • Bindung der Client-ID. Die Bindung der Client-ID an die ausgegebenen Zugangsdaten verhindert, dass ein Gerät sich als ein anderes ausgibt oder die Session eines anderen übernimmt, denn MQTT trennt die ältere Verbindung, sobald sich eine doppelte Client-ID verbindet.
  • Schutz vor Brute-Force-Angriffen. Gemeinsame Infrastruktur ist ein größeres Ziel. Ratenbegrenzung und das Sperren von Adressen nach wiederholt fehlgeschlagenen Anmeldungen schützen alle Mandanten zugleich.
  • Rotation von Geheimnissen. Mandanten brauchen eine Möglichkeit, Zugangsdaten zu rotieren, ohne den Betreiber um einen Neustart bitten zu müssen.

Baustein 3: Ressourcenkontingente und Noisy Neighbors

Das Noisy-Neighbor-Problem ist das klassische Risiko gemeinsamer Infrastruktur. Ein Firmware-Fehler eines Mandanten, der in einer engen Schleife neu verbindet, oder ein Skript, das so schnell wie möglich veröffentlicht, kann CPU, Speicher und Bandbreite verbrauchen, die andere Mandanten brauchen. Kontingente machen aus diesem Risiko ein begrenztes Problem pro Mandant.

Ressource Warum begrenzen Typische Durchsetzung
Gleichzeitige Verbindungen Speicher und File Descriptors pro Verbindung CONNECT oberhalb des Limits ablehnen
Nachrichtenrate CPU- und Fan-out-Kosten Drosseln oder trennen, MQTT-5-Reason-Code
Maximale Nachrichtengröße Speicherspitzen, Bandbreite Zu große PUBLISH ablehnen
Abonnements pro Client Größe der Routing-Tabelle SUBSCRIBE oberhalb des Limits ablehnen
QoS-Stufe Inflight-Zustand und Wiederholungen Herabstufen oder ablehnen
Session-Ablauf Gespeicherte Offline-Nachrichten Ablaufintervall begrenzen
Retained Messages Speicherplatz Limits für Anzahl und Größe

MQTT 5 hilft hier, weil der Broker sich erklären kann. Der Reason Code 0x97 (Quota exceeded) teilt einem gut geschriebenen Client mit, dass er ein Limit erreicht hat, statt ihn raten zu lassen, warum ein Publish verworfen wurde. Zur Client-Seite der Limits siehe Verbindungskontingente von MQTT-Brokern.

Geteilter oder dedizierter Cluster?

Mandantenfähigkeit ist ein Spektrum. Am einen Ende teilen sich alle Mandanten einen Cluster mit logischer Isolation. Am anderen Ende erhält jeder Mandant eigene Maschinen. Die Tabelle fasst den Kompromiss zusammen.

Aspekt Geteilter mandantenfähiger Cluster Dedizierter Cluster pro Mandant
Kosteneffizienz Hoch, Kapazität wird gebündelt Geringer, Kapazität wird reserviert
Isolation Logisch (Identität, Namespace, Kontingente) Physisch
Anfälligkeit für Noisy Neighbors Durch Kontingente begrenzt Keine durch andere Mandanten
Bereitstellungszeit Sekunden Länger
Individuelle Limits Tarifbasiert Auf den Mandanten zugeschnitten
Typischer Einsatz Prototypen, kleine und mittlere Flotten Große Flotten, strenge Anforderungen

Die meisten Anbieter bieten beides an und lassen einen Mandanten mit wachsendem Bedarf von einem zum anderen wechseln. Die tiefere Frage, wie stark Kunden getrennt werden sollten, behandelt Mandantenisolation bei MQTT.

Einen mandantenfähigen Broker betreiben

Isolation zu entwerfen ist die halbe Arbeit. Sie zu betreiben ist die andere Hälfte:

  • Beobachtbarkeit pro Mandant. Metriken brauchen eine Mandanten-Dimension: Verbindungen, Nachrichtenraten und Kontingent-Ablehnungen pro Mandant, nicht nur Summen für den Cluster.
  • Faire Upgrades. Rolling Restarts sollten die Reconnect-Last verteilen, und Clients müssen ein randomisiertes Backoff verwenden, damit nicht Tausende Geräte vieler Mandanten im selben Augenblick zurückkehren.
  • Umgang mit Missbrauch. Flood-Schutz muss auf den verursachenden Mandanten oder Client wirken, nicht auf den ganzen Cluster.
  • Lebenszyklus von Mandanten. Beim Anlegen, Sperren und Löschen von Mandanten müssen Sessions, Retained Messages und Zugangsdaten vollständig bereinigt werden.

So setzt ConnectMQ Mandantenfähigkeit um

ConnectMQ ist als mandantenfähige Plattform aufgebaut. In den Serverless-Tarifen teilen sich viele Broker einen Cluster, und jeder Broker ist von den anderen isoliert: Er hat einen eigenen generierten Benutzernamen, ein Passwort und eine Client-ID, Client-IDs sind an die ausgegebenen Zugangsdaten gebunden, und tarifabhängige Kontingente begrenzen Verbindungen, QoS und Nachrichtengröße. Der kostenlose Serverless-Tarif erlaubt bis zu 25 Verbindungen, QoS bis 1 und Nachrichten bis 256 KB; der kostenpflichtige Serverless-Tarif erhöht dies auf bis zu 1.000 Verbindungen, QoS 2, Nachrichten bis 1 MB und Shared Subscriptions.

Flood-Schutz und IP-Sperren nach wiederholt fehlgeschlagenen Anmeldungen schützen jeden Mandanten auf dem geteilten Cluster. Überschreitet ein Client seine Limits, erhalten MQTT-5-Clients den Reason Code 0x97, sodass die Ursache sichtbar ist. Reicht logische Isolation nicht aus, bietet der Dedicated-Tarif einen isolierten Cluster, und BYOC betreibt den Broker in Ihrem eigenen Cloud-Konto, während ConnectMQ ihn weiterhin verwaltet.

Ein mandantenbezogenes Topic-Layout ausprobieren

Selbst innerhalb Ihres eigenen Brokers macht ein konsistentes Topic-Layout mandantenfähige Anwendungen leichter nachvollziehbar. Dieses MQTT.js-Beispiel veröffentlicht auf ein Topic mit Mandanten- und Standortpräfix auf dem öffentlichen MQTT-Broker; denken Sie daran, dass der öffentliche MQTT-Broker für jeden lesbar ist und sich nur für Tests und Prototypen eignet, nicht für Produktionsdaten.

const mqtt = require("mqtt");

const tenant = "tenant-demo-91b2";
const base = `connectmq/demo/${tenant}`;
const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: `${tenant}-gw-01`,
  protocolVersion: 5,
});

client.on("connect", () => {
  client.subscribe(`${base}/+/+/temperature`, { qos: 1 });
  setInterval(() => {
    const payload = JSON.stringify({ value: 20 + Math.random() * 5, ts: Date.now() });
    client.publish(`${base}/site-a/line-1/temperature`, payload, { qos: 1 });
  }, 5000);
});

client.on("message", (topic, message) => console.log(topic, message.toString()));
client.on("error", (err) => console.error("MQTT error:", err.message));

Ergänzen Sie auf einem privaten ConnectMQ-Broker username: "YOUR_USERNAME" und password: "YOUR_PASSWORD" und verwenden Sie YOUR_CLIENT_ID aus dem Portal.

Starten Sie mit ConnectMQ

Sparen Sie sich den eigenen Aufbau der Mandantenisolation. Erstellen Sie einen kostenlosen, isolierten Serverless-Broker unter app.connectmq.com, ganz ohne Kreditkarte, und skalieren Sie auf Dedicated oder BYOC, wenn Sie eine stärkere Trennung brauchen. Erfahren Sie mehr über das Modell des verwalteten MQTT-Brokers oder lesen Sie den vollständigen Leitfaden zum Cloud-MQTT-Broker.

Häufig gestellte Fragen

Reicht ein Topic-Präfix aus, um Mandanten zu trennen?

Nur, wenn der Broker es durchsetzt. Ein Präfix ohne Durchsetzung ist eine Namenskonvention; ein Client, der # abonniert, würde trotzdem die Nachrichten anderer Mandanten sehen.

Was ist das Noisy-Neighbor-Problem bei MQTT?

Es tritt auf, wenn der starke oder fehlerhafte Datenverkehr eines Mandanten gemeinsame Broker-Ressourcen verbraucht und den Dienst für andere verschlechtert. Kontingente pro Mandant und Flood-Schutz begrenzen den Schaden.

Wirkt sich ein mandantenfähiger Broker auf meinen Client-Code aus?

In der Regel nicht. Clients verwenden Standard-MQTT; die Mandantengrenze wird durch die Zugangsdaten und den Endpunkt definiert, mit denen Sie sich verbinden.

Wann sollte ich von einem geteilten zu einem dedizierten Broker wechseln?

Wechseln Sie, wenn Sie planbare, nicht geteilte Kapazität brauchen, Limits oberhalb der Kontingente geteilter Tarife benötigen oder eine Richtlinie physische Isolation verlangt.

Verwandte Artikel

BYOC-MQTT-Broker: Bring Your Own Cloud einfach erklärt

Ein BYOC-MQTT-Broker läuft in Ihrem Cloud-Konto, wird aber von einem Anbieter betrieben. Erfahren Sie, wie das Modell funktioniert, wie die Verantwortung aufgeteilt ist und wie Sie Ihr Konto darauf vorbereiten.

8 Min. Lesezeit

Google Cloud IoT Core Alternative: Optionen und Migration nach der Abschaltung

Google hat Cloud IoT Core im August 2023 eingestellt. Dieser Leitfaden vergleicht die realistischen Alternativen, überträgt IoT-Core-Konzepte auf reines MQTT und zeigt, wie Sie Geräte zu einem verwalteten MQTT-Broker umziehen, während die Daten weiter in Google Cloud fließen.

8 Min. Lesezeit

MQTT-Nachrichten pro Sekunde: Durchsatz abschätzen und messen

Die Durchsatzplanung für MQTT läuft auf wenige Formeln und eine ehrliche Messung hinaus. Erfahren Sie, wie Sie eingehende und ausgehende Nachrichten pro Sekunde abschätzen, Spitzen berücksichtigen und das Ergebnis einem Broker-Plan zuordnen.

7 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.