Lasttests

Belastungstests des Brokers auf zwei Prüfständen — über das Netzwerk und über Loopback —, um das Verhalten des Brokers von dem der Umgebung zu trennen. Nachfolgend: Methodik, vollständige Tabellen und kurze Befunde.

Bericht herunterladen (PDF)

Prüfstände

Datum: 24. Juli 2026 · Protokoll: MQTT 3.1.1 · Werkzeug: eigener Lastclient cmd/loadtest auf Basis des projekteigenen Codecs, ohne fremde MQTT-Bibliothek.

Getestet wurde auf zwei Prüfständen, um das Verhalten des Brokers vom Einfluss der Umgebung zu trennen: Netzwerk gegen Loopback, bescheidene gegen starke Hardware.

Prüfstand A — über das NetzwerkPrüfstand B — Loopback
CPU des Brokers12 Kerne2× Xeon E5-2690 v4 @ 2,6 GHz (28 Kerne / 56 Threads)
RAM des Brokers16 GB128 GB
Adresse192.168.1.84:1883 (LAN)127.0.0.1:1883 (Loopback)
LastgeneratorEigene Maschine im LANDieselbe Maschine wie der Broker
Ephemere Ports des Clients16 384 (Standard)55 000 (erweitert)
Wie der Vergleich zu lesen ist. Die Prüfstände sind nicht gleichwertig und beantworten verschiedene Fragen. Prüfstand A zeigt den Betrieb über ein Netzwerk mit eigenem Generator. Prüfstand B entfernt das Netzwerk (nahezu keine Latenz) und gibt dem Broker starke Hardware, doch Generator und Broker teilen sich dieselben Kerne. Latenz und Fan-out lassen sich also direkt vergleichen, die Aufnahmerate dagegen nicht: Auf Prüfstand B stiehlt der Client dem Broker Kerne.

Zusammenfassung

  • Latenz. Über das Netzwerk beträgt die Ende-zu-Ende-Latenz „Publisher → Broker → Subscriber“ bei normaler Last etwa 1 ms; über Loopback sind es 73 µs (~16× weniger, ohne Netzwerk).
  • Verbindungen. Über das Netzwerk hielt der Broker 10 000 Sitzungen ohne Ausfälle (darüber hinaus stießen wir an die Portgrenze des Clients). Auf starker Hardware über Loopback: 30 000 ohne Ausfälle und ~41 000 bei einem Versuch mit 50 000 (die Grenze einer einzelnen Maschine, nicht des Brokers).
  • Aufnahme. Der Spitzenwert über das Netzwerk lag bei ≈277 000 Nachrichten/s; über Loopback ist die Aufnahme geringer (≈185 000/s), weil der Generator mit dem Broker um Kerne konkurriert.
  • Fan-out (Verteilung). Auf starker Hardware stellte der Broker ≈1 350 000 Nachrichten/s an Abonnenten zu (Fan-out ×100) gegenüber ≈22 000/s über das Netzwerk.
  • Robustheit. Auf keinem Prüfstand stürzte der Broker ab oder blieb hängen. Bei Überlast werden QoS-0-Nachrichten an nachhinkende Abonnenten geordnet verworfen; das Broker-Log enthält über alle Läufe hinweg nicht einen einzigen Fehler.

Kapazität an gleichzeitigen Verbindungen

Jede Verbindung ist ein vollständiger Zyklus CONNECT → CONNACK mit Authentifizierung; anschließend wird die Sitzung offen gehalten (mit PINGREQ geprüft).

Prüfstand A — über das Netzwerk

ZielAufgebautFehlgeschlagenAufbau p50p99
10100146 ms162 ms
1001000702 ms1,12 s
1 0001 00004,21 s9,78 s
5 0005 00004,64 s8,59 s
10 00010 00004,92 s10,52 s
15 00014 8791217,43 s14,09 s

Prüfstand B — Loopback (stufenweiser Aufbau)

ZielAufgebautFehlgeschlagenAufbau p50p99
1 0001 0000886 ms1,06 s
10 00010 0000903 ms1,55 s
30 00030 0000923 ms1,90 s
50 00041 2190984 ms1,90 s

Analyse

  • Über das Netzwerk bis 10 000 — kein einziger Ausfall; die 121 Fehlschläge bei 15 000 sind erschöpfte ephemere Ports des Clients (16 384). Das ist die Grenze des Generators, nicht des Brokers.
  • Über Loopback hielt der Broker nach Erweiterung des Portbereichs 30 000 Sitzungen fehlerfrei; bei 50 000 waren am Ende des Haltens noch etwa 41 000 am Leben — beide Seiten teilen sich eine Maschine. Das Broker-Log blieb durchgehend sauber, ohne Fehler.
  • Nebenbefund. Über Loopback löst ein zu scharfer Verbindungsstoß (1 000 gleichzeitige dials) ein connection refused aus — der Accept-Backlog läuft über: ohne Netzwerkverzögerung treffen alle SYN gleichzeitig ein. Ein stufenweiser Aufbau (200 auf einmal) beseitigt den Effekt vollständig. Über ein Netzwerk glättet die Latenz den Stoß von selbst.

Aufnahmedurchsatz

Ein Pool von Publishern veröffentlicht so schnell wie möglich; gemessen wird die Aufnahmerate des Brokers.

QoS 0 · 64 Byte Payload

PublisherPrüfstand A (Netzwerk)Prüfstand B (Loopback)
10271 006/s185 012/s
100236 422/s101 457/s
500103 546/s125 324/s

Die Aufnahme ist über das Netzwerk höher — nicht weil der Broker auf Prüfstand A schneller wäre, sondern weil der Generator dort auf einer eigenen Maschine läuft. Über Loopback teilen sich Client und Broker dieselben Kerne, was die gemeinsame Rate deckelt.

QoS 1 (mit PUBACK-Bestätigung) · 64 B

PublisherPrüfstand A (Netzwerk)Prüfstand B (Loopback)
1010 292/s63 606/s
10022 085/s48 983/s

Der Testclient für QoS 1 arbeitet synchron (er wartet nach jeder Nachricht auf ein PUBACK) und ist damit an die Umlaufzeit gebunden. Über Loopback ist die Umlaufzeit nahezu null, daher der Gewinn um das ~6-Fache. Das zeigt deutlich, dass die QoS-1-Zahlen von der Netzlatenz bestimmt werden und nicht vom Broker.

Durchlauf über Nachrichtengrößen · QoS 0 · 50 Publisher

GrößePrüfstand A (Netzwerk)Prüfstand B (Loopback)
64 B277 198/s · 17,7 MB/s101 961/s · 6,5 MB/s
256 B124 997/s · 32,0 MB/s102 029/s · 26,1 MB/s
1 024 B38 458/s · 39,4 MB/s102 151/s · 104,6 MB/s

Zwei verschiedene Obergrenzen:

  • Über das Netzwerk stoßen wir bei ≈40 MB/s an die Leitung: Wächst die Nachricht, fällt msg/s, während MB/s nahe am Limit bleibt.
  • Über Loopback ist die Leitung riesig, also bleibt die Nachrichtenzahl konstant (~102 000/s bei 50 Verbindungen) und das Volumen steigt auf 104,6 MB/s. Hier ist die Verarbeitung je Nachricht (CPU) der Engpass, nicht die Bytes.

Ende-zu-Ende-Zustellung

In den Nachrichtenrumpf wird ein Zeitstempel eingebettet; gemessen werden die tatsächliche Zustellung und die Ende-zu-Ende-Latenz. Fan-out bedeutet die Zustellung an jeden Abonnenten, dessen Filter passt.

Prüfstand A — über das Netzwerk

SzenarioPublishZustellungMittel / p50 / p99
10 Sub / 10 Pub / 100 Nachr./s — normal986/s9 863/s1,17 / 1,0 / 3,6 ms
100 Sub / 10 Pub / ungedrosselt261 551/s22 351/s780 / 453 / 678 ms
100 Sub / 10 Pub / 500 Nachr./s4 934/s12 150/s1,87 / 1,77 / 2,83 s
1 000 Sub / 5 Pub / 100 Nachr./s494/s178 961/s2,29 s / 480 / 952 ms

Prüfstand B — Loopback

SzenarioPublishZustellungMittel / p50 / p99
10 Sub / 10 Pub / 100 Nachr./s — normal987/s9 867/s73 / ~0 / 555 µs
100 Sub / 10 Pub / ungedrosselt47 557/s1 353 431/s514 / 135 / 251 ms
100 Sub / 10 Pub / 500 Nachr./s3 608/s360 834/s17,1 / 10,5 / 71,6 ms
1 000 Sub / 5 Pub / 100 Nachr./s494/s183 746/s4,73 / 4,54 / 15,1 ms

Analyse

  • Latenz bei normaler Last: 1,17 ms über das Netzwerk gegenüber 73 µs über Loopback. Der Unterschied ist der Netzwerkweg.
  • Verteilung unter Last: Die starke Maschine stellte ≈1,35 Millionen Nachrichten/s an Abonnenten zu (Fan-out ×100) — zwei Größenordnungen über dem Netzwerk-Prüfstand (22 Tsd./s), wo sowohl Broker als auch Leitung klein sind.
  • In Szenarien mit hohem Fan-out wird auch der Generator zum Engpass (alle Abonnenten in einem Prozess auf einer Maschine), daher sind die Spitzenwerte der Zustellung eine Untergrenze dessen, was der Broker kann.

Direkter Vergleich

KennwertPrüfstand A — Netzwerk (12 Kerne)Prüfstand B — Loopback (28 Kerne)
Verbindungen ohne Ausfälle10 00030 000
Spitzenwert Verbindungen14 879 (Clientgrenze)~41 000 (Grenze einer Maschine)
Aufnahme QoS 0 (64 B), Spitze271 006/s185 012/s
Aufnahme QoS 1 (64 B), Spitze22 085/s63 606/s
Volumengrenze≈40 MB/s (Leitung)≈105 MB/s (CPU)
Latenz (normal), Median1,0 ms~0 (73 µs im Mittel)
Zustellung bei Fan-out, Spitze22 351/s1 353 431/s
Fehler im Broker-Logkeinekeine

Vorbehalte zur Methodik

  • Die Aufnahmerate ist zwischen den Prüfständen nicht direkt vergleichbar: Auf Prüfstand B teilen sich Generator und Broker die Kerne; auf Prüfstand A ist der Generator eine eigene Maschine.
  • Die Last kommt auf jedem Prüfstand von einer einzigen Clientmaschine; in manchen Szenarien (großes Fan-out, Zehntausende Verbindungen) ist diese Maschine der Engpass und nicht der Broker.
  • Der Testclient für QoS 1 arbeitet synchron — die QoS-1-Zahlen bleiben hinter dem Möglichen des Brokers zurück.
  • Systemkennwerte des Brokers (CPU/RAM während der Läufe) wurden nicht erfasst; der Zustand des Servers wird aus seinem Log (keine Fehler) und aus dem Verhalten der Clientseite geschlossen.

Nachvollziehen

Jeder Lauf wird aus einer einzigen loadtest-Binärdatei gestartet; nachfolgend die Befehle für die drei Modi.

go build -o loadtest ./cmd/loadtest

# Verbindungskapazität (stufenweiser Aufbau gegen Accept-Backlog)
./loadtest -addr HOST:1883 -user myelx -pass *** \
    -mode conn -levels 1000,10000,30000,50000 -hold 3s -dial-concurrency 200

# Aufnahmedurchsatz
./loadtest -addr HOST:1883 -user myelx -pass *** \
    -mode pub -pubs 10 -qos 0 -payload 64 -duration 10s

# Ende-zu-Ende-Zustellung und Latenz
./loadtest -addr HOST:1883 -user myelx -pass *** \
    -mode pubsub -subs 10 -pubs 10 -qos 0 -rate 100 -payload 64 -duration 10s