emqtt-bench (binary'nin adı emqtt_bench), EMQ'nun Erlang ile yazdığı, tek bir makineden on binlerce bağlantı açıp publish ve subscribe yükü üretebilen açık kaynak bir MQTT benchmark aracıdır. Üç komutu — conn, sub ve pub — ve uzun bir flag listesi vardır. Bu rehberde her komutu, gerçekten önemli olan flag'leri, TLS ve WebSocket kullanımını, gecikme ölçümünü ve aracın yazdırdıklarının nasıl okunacağını anlatıyoruz.
Daha geniş yöntem — neyin ölçüleceği ve bir benchmark'ın nasıl planlanacağı — için MQTT broker yük testi yazısına bakın. Bu sayfa aracın kendisi için başvuru kaynağıdır.
Kurulum veya Docker ile çalıştırma
En hızlı yol, entrypoint'i emqtt_bench olan Docker imajıdır:
docker run --rm -it emqx/emqtt-bench pub --helpUzun veya çok büyük çalıştırmalarda yerel kurulum, Docker ağ katmanının ek yükünü ortadan kaldırır. Önceden derlenmiş paketler projenin GitHub releases sayfasında yayımlanır. Kaynaktan derlemek için güncel bir Erlang/OTP ve libatomic gerekir:
git clone https://github.com/emqx/emqtt-bench.git
cd emqtt-bench
make # QUIC derlemesi başarısız olursa BUILD_WITHOUT_QUIC=1 make
./emqtt_bench conn --helpHerhangi bir benchmark'tan önce host, port ve kimlik bilgilerini online MQTT client üzerinde tek bir client ile elle kontrol edin. Bir bağlantı başarısız oluyorsa iki bin bağlantı yalnızca daha hızlı başarısız olur. Örnekler, hızlı kontroller için uygun paylaşımlı bir endpoint olan broker.connectmq.com adresini kullanır; gerçek benchmark'ları -h değerini ve kimlik bilgilerini değiştirerek kendi özel broker instance'ınıza karşı çalıştırın.
Tüm komutlarda ortak seçenekler
| Flag | Anlamı | Varsayılan |
|---|---|---|
-h, --host | Broker host'u; virgülle ayrılmış liste client'ları birden çok host'a dağıtır | localhost |
-p, --port | Broker portu | 1883 |
-V, --version | MQTT protokol sürümü: 3 (3.1), 4 (3.1.1) veya 5 | 5 |
-c, --count | Başlatılacak client sayısı | 200 |
-i, --interval | Yeni bağlantılar arasındaki milisaniye | 10 |
-R, --connrate | Saniye başına bağlantı; 0 ise -i kullanılır | 0 |
-u, -P | Kullanıcı adı ve şifre | yok |
-k, --keepalive | Saniye cinsinden keep alive | 300 |
-C, --clean | Clean session / clean start | true |
-x, --session-expiry | Saniye cinsinden MQTT 5 session expiry interval | 0 |
--prefix | Client ID öneki (ayarlanırsa rastgele son ek eklenmez) | <host>_bench_<cmd>_<random>_<n> |
--shortids | Kısa client ID'ler: sıra numarası ya da önek + numara | false |
-n, --startnumber | İlk sıra numarası; birden çok bench instance'ı arasında ID çakışmasını önler | 0 |
--ifaddr | Bağlanılacak yerel IP adres(ler)i, virgülle ayrılmış | sistem varsayılanı |
--reconnect | Bağlantı koptuktan sonra yeniden bağlanma denemeleri | 0 (kapalı) |
--num-retry-connect | İlk bağlantı için yeniden deneme sayısı | 0 |
-l, --lowmem | Düşük bellek modu: client başına daha az RAM, daha fazla CPU | kapalı |
İki ayrıntı sık sık kafa karıştırır. Birincisi, varsayılan protokol sürümü MQTT 5'tir; yalnızca 3.1.1 konuşan bir broker'ı veya yapılandırmayı test etmek için -V 4 verin. İkincisi, 300 sn'lik varsayılan keep alive çoğu cihazın kullandığından çok daha uzundur; boştaki bağlantı davranışını test ediyorsanız -k değerini filonuzun değerine ayarlayın.
Client ID'ler broker başına benzersiz olmalıdır. Aynı broker'a karşı birden çok emqtt-bench süreci çalıştırıyorsanız her birine kendi --prefix değerini veya -n aralığını verin — tekrarlanan ID'ler rastgele kopmalar gibi görünen session takeover durumlarına yol açar. ID formatlarını client ID üretici ile önizleyebilirsiniz.
conn: bağlantı kapasitesi
conn yalnızca bağlanır ve bağlantıları açık tutar. "Broker aynı anda kaç client'ı taşıyabilir ve onları ne hızla kabul eder?" sorusunu yanıtlar.
docker run --rm -it emqx/emqtt-bench conn \
-h broker.connectmq.com -p 1883 \
-c 5000 -R 500 -k 60 \
-u "$MQTT_USER" -P "$MQTT_PASS"connect_succ değerinin hedefe kadar yükseldiğini ve connect_fail değerinin sıfırda kaldığını izleyin. Bir kesintiden sonra tüm cihazların geri döndüğü bir yeniden bağlanma fırtınası, -R değeri yükseltilerek simüle edilir. Daha fazla senaryo bağlantı stres testi rehberinde.
sub: subscriber'lar
sub client'ları bağlar, her birini bir topic'e subscribe eder ve gelenleri sayar.
| Flag | Anlamı | Varsayılan |
|---|---|---|
-t, --topic | Yer tutucular içerebilen topic filtresi (aşağıya bakın) | zorunlu |
-q, --qos | Subscription QoS'u | 0 |
--payload-hdrs | Publisher'ın eklediği başlıkları işler (ts, cnt64) | yok |
docker run --rm -it emqx/emqtt-bench sub \
-h broker.connectmq.com -p 1883 \
-c 100 -i 5 -q 1 \
-t 'testmqtt/bench/%i/data' \
-u "$MQTT_USER" -P "$MQTT_PASS"pub: publisher'lar
pub client'ları bağlar ve her client için sabit bir aralıkla publish eder.
| Flag | Anlamı | Varsayılan |
|---|---|---|
-t, --topic | Yer tutucular içerebilen publish topic'i | zorunlu |
-I, --interval_of_msg | Client başına mesajlar arası milisaniye | 1000 |
-s, --size | Bayt cinsinden payload boyutu | 256 |
-m, --message | Sabit payload ya da template://<file> | rastgele baytlar |
-q, --qos | Publish QoS'u | 0 |
-r, --retain | Retain bayrağını ayarlar | false |
-L, --limit | Bu kadar mesajdan sonra durur; 0 = sınırsız | 0 |
-F, --inflight | Client başına onaylanmamış en fazla QoS 1/2 mesajı; 0 = sınırsız | 1 |
-w, --wait-before-publishing | Tüm publisher'lar bağlanmayı denedikten sonra publish'e başlar | false |
--payload-hdrs | Payload'un başına ts (timestamp) ve/veya cnt64 (sayaç) ekler | yok |
docker run --rm -it emqx/emqtt-bench pub \
-h broker.connectmq.com -p 1883 \
-c 100 -I 100 -s 512 -q 1 -F 10 -w \
-t 'testmqtt/bench/%i/data' \
-u "$MQTT_USER" -P "$MQTT_PASS"Hedef hız client sayısı × (1000 / -I) şeklindedir. -F değerine dikkat edin: varsayılan inflight penceresi 1 iken her QoS 1 client'ı bir sonraki mesajı göndermeden önce her PUBACK'i bekler; yüksek gecikmede client aralığına asla yetişemez. pub_overrun artıyorsa client takvimini tutturamamıştır; -F değerini artırın veya hızı düşürün. Throughput testi stratejileri MQTT throughput testi rehberinde anlatılıyor.
Topic yer tutucuları
-t içindeki yer tutucular, tek bir komutun birçok farklı topic oluşturmasını sağlar:
| Yer tutucu | Neye dönüşür |
|---|---|
%i | Client sıra numarası (-n kaydırması dahil) |
%c | Client ID |
%u | -u ile verilen kullanıcı adı |
%s | Mesaj sıra numarası (yalnızca pub) |
%rand_N | 1 ile N arasında rastgele tam sayı |
Her iki tarafta da %i kullanmak — aynı -c ile pub -t 'testmqtt/bench/%i/data' ve sub -t 'testmqtt/bench/%i/data' — publisher N'yi subscriber N ile eşler: bire bir yönlendirme. Buna karşılık testmqtt/bench/+/data üzerindeki tek bir subscriber fan-in'i, tek topic üzerindeki çok sayıda subscriber ise fan-out'u ölçer. Filtrelerinizi topic matcher ile kontrol edin.
TLS, WebSocket ve QUIC
| Flag | Anlamı |
|---|---|
-S, --ssl | TLS'i etkinleştirir |
--ssl-version | Belirli bir TLS sürümünü zorlar (--ssl anlamına gelir) |
--cacertfile | Broker'ı doğrulamak için CA paketi |
--certfile, --keyfile | Client sertifikası ve anahtarı (karşılıklı TLS) |
--ciphers | Cipher suite'leri kısıtlar |
--ws | WebSocket transport'unu kullanır |
--quic | QUIC üzerinden MQTT kullanır (destekleyen broker'larda) |
# TLS üzerinden MQTT
emqtt_bench conn -h broker.connectmq.com -p 8883 --ssl \
--cacertfile /etc/ssl/certs/ca-certificates.crt \
-c 1000 -R 100 -u "$MQTT_USER" -P "$MQTT_PASS"
# Güvenli WebSocket üzerinden MQTT
emqtt_bench pub -h broker.connectmq.com -p 8084 --ws --ssl \
-c 50 -I 1000 -t 'testmqtt/bench/%i/ws' -u "$MQTT_USER" -P "$MQTT_PASS"emqtt-bench'te WebSocket yolu için ayrı bir flag yoktur; alttaki emqtt client'ı /mqtt yolunu kullanır ve bu, örneklerdeki endpoint ile eşleşir. Aynı conn çalıştırmasını 1883 ve 8883 üzerinden karşılaştırmak handshake maliyetini doğrudan gösterir — bkz. MQTT TLS performans testi.
Gecikmeyi ölçme
Subscriber'ı ve publisher'ı aynı --payload-hdrs ts ile başlatın. Publisher her payload'un başına milisaniye cinsinden bir timestamp yazar; subscriber mesaj geldiğinde bunu kendi saatinden çıkarır:
# terminal 1
emqtt_bench sub -h broker.connectmq.com -c 50 -q 1 \
-t 'testmqtt/bench/%i/lat' --payload-hdrs ts -u "$MQTT_USER" -P "$MQTT_PASS"
# terminal 2
emqtt_bench pub -h broker.connectmq.com -c 50 -I 200 -q 1 \
-t 'testmqtt/bench/%i/lat' --payload-hdrs ts -u "$MQTT_USER" -P "$MQTT_PASS"Subscriber bundan sonra bir publish_latency avg=…ms satırı yazdırır. Bu bir ortalamadır; percentile'lar için --prometheus seçeneğini açın (bir e2e_latency histogramı sunar) ya da yük testi rehberindeki script'i kullanın. Timestamp publisher'ın saatinden geldiği için ikisini aynı makinede çalıştırın ya da makinelerin saatlerini senkron tutun.
Çıktıyı okuma
emqtt-bench her saniye, değişen her sayaç için <süre> <sayaç> total=<n> rate=<n>/sec biçiminde bir satır yazdırır:
10s connect_succ total=100 rate=0.00/sec
10s pub total=9871 rate=1000.12/sec
10s pub_succ total=9862 rate=999.40/sec| Sayaç | Anlamı |
|---|---|
connect_succ / connect_fail | Kabul edilen / başarısız bağlantılar |
connect_retried, reconnect_succ | Yeniden denemeler ve başarılı yeniden bağlanmalar |
connection_refused, connection_timeout, unreachable | Bağlantıların neden başarısız olduğu |
connection_idle | Boşta kalan bağlantılar |
sub / sub_fail | Kabul edilen / reddedilen subscription'lar |
pub / pub_succ / pub_fail | Gönderilen / onaylanan / başarısız mesajlar |
pub_overrun | Bir client publish aralığını tutturamadı |
pub_nosub | Broker eşleşen subscriber olmadığını bildirdi (MQTT 5) |
recv | Subscriber'ların aldığı mesajlar |
publish_latency | Ortalama uçtan uca gecikme (--payload-hdrs ts ile) |
Sağlıklı tablo şudur: pub ve recv hızları hedefinizle ve birbiriyle eşleşir, pub_overrun sıfırda kalır ve hiçbir hata sayacı görünmez. Yuvarlak bir sayıya (1.024, 65.535) yakın yükselen connection_timeout veya connect_fail genellikle yük üreticideki limitlere işaret eder. Broker'ın reason code'larını reason code aracı ile sorgulayın.
Yük üreticiyi ölçeklendirme
- Dosya tanımlayıcıları. Büyük
connçalıştırmalarından önceulimit -ndeğerini-cdeğerinin epey üzerine çıkarın. - Portlar. Tek bir kaynak IP, bir broker adresi ve portuna yalnızca yaklaşık 64K bağlantı açabilir.
--ifaddr 10.0.0.11,10.0.0.12ya da birden çok makine kullanın ve yerel port aralığınısysctlile genişletin. - Bellek. Çok yüksek client sayıları için daha fazla CPU pahasına
-lekleyin. - CPU. Üretici yaklaşık %80 CPU'nun üzerine çıkıyorsa sayılarınız broker'ı değil üreticiyi anlatır.
Benchmark trafiğini online client'ta izleyin
emqtt-bench, komut satırından bir MQTT broker'ına gerçekçi bağlantı ve mesaj yükü bindirmenin en hızlı yoludur. Yükü şekillendiren birkaç flag'i — -c, -R, -I, -q, -F ve topic yer tutucuları — öğrenin, TLS ve protokol sürümünün production ile eşleştiğinden emin olun ve sayaçları çalıştırmadan çalıştırmaya karşılaştırabileceğiniz hızlar olarak okuyun.
Sıkça sorulan sorular
emqtt-bench'te -i ile -R arasındaki fark nedir?
-i (--interval), yeni bağlantılar arasındaki milisaniye cinsinden beklemedir, varsayılanı 10'dur. -R (--connrate) bunun yerine saniye başına bağlantı hızını belirler; 0 olduğunda (varsayılan) emqtt-bench yeniden aralığı kullanır.
emqtt-bench ile gecikmeyi nasıl ölçerim?
Subscriber'ı ve publisher'ı aynı --payload-hdrs ts seçeneğiyle başlatın. Publisher her payload'un başına milisaniye cinsinden bir timestamp ekler, subscriber da ortalama uçtan uca gecikmeyi içeren bir publish_latency satırı yazdırır. İkisini aynı makinede çalıştırın ya da saatleri senkron tutun.
emqtt-bench neden 64.000 bağlantı civarında duruyor?
Tek bir kaynak IP, aynı broker adresine ve portuna yalnızca yaklaşık 64K TCP bağlantısı açabilir. Client'ları --ifaddr ile birden çok yerel adrese dağıtın ya da emqtt-bench'i birkaç makinede çalıştırın ve ulimit -n değerini artırın.



