MQTT maksimum QoS, hizmet kalitesinin insanları en çok şaşırtan kısmıdır: QoS 2 ile publish edip bir mesajı yine de QoS 0 ile alabilirsiniz. Bir teslimatta gerçekten kullanılan seviye; publisher'a, subscriber'a ve broker'ın kendi sınırlarına bağlıdır. Bu makalede efektif QoS'un nasıl hesaplandığını, broker'ların bir maksimumu nasıl bildirip uyguladığını ve bağlantınızın tam olarak neyi aldığını nasıl test edeceğinizi öğreneceksiniz.
QoS Her Adımda Ayrı Belirlenir
MQTT'nin üç QoS seviyesi vardır: 0 (en fazla bir kez), 1 (en az bir kez) ve 2 (tam olarak bir kez). Bunlar sizin için yeniyse MQTT QoS seviyeleri yazısıyla başlayın.
Temel gerçek şudur: QoS uçtan uca değildir. Bir mesaj iki ayrı adımda ilerler:
- Publisher'dan broker'a; publisher'ın o PUBLISH için seçtiği QoS ile.
- Broker'dan her subscriber'a; broker'ın o subscription için hesapladığı QoS ile.
Her adımın kendi el sıkışması vardır. Publisher'ın PUBACK'i subscriber'dan değil broker'dan gelir; bu yüzden bir publisher, herhangi bir subscriber'ın mesajı alıp almadığını asla bilemez.
Efektif QoS Nasıl Hesaplanır?
Broker her subscriber için iki değerden düşük olanıyla teslim eder: gelen PUBLISH'in QoS'u ve eşleşen subscription için verilen (granted) QoS.
| Publish QoS | Subscription QoS | Teslim edilen QoS |
|---|---|---|
| 0 | 2 | 0 |
| 1 | 0 | 0 |
| 1 | 2 | 1 |
| 2 | 1 | 1 |
| 2 | 2 | 2 |
Pratikte iki sonuç önemlidir:
- QoS 2 ile subscribe olmak hiçbir şeyi yükseltmez. Bir sensör QoS 0 ile publish ediyorsa, her subscriber ne istemiş olursa olsun QoS 0 alır.
- Bir subscriber bilinçli olarak düşürebilir. Yalnızca en son değerle ilgilenen bir dashboard, QoS 1 ile publish edilen telemetriye QoS 0 ile subscribe olarak kendi bağlantısındaki onaylardan tasarruf edebilir.
Bir subscription filtresi diğeriyle çakışıyorsa (örneğin plant/# ve plant/line1/+), broker mesajı eşleşen en yüksek QoS ile bir kez veya uygulamaya bağlı olarak MQTT 5'te subscription başına bir kez teslim edebilir. Mümkünse farklı QoS'lu çakışan subscription'lardan kaçının.
Broker'lar QoS'u Nasıl Sınırlar?
Bir broker'ın her client için her seviyeyi desteklemesi gerekmez. Bunu belirtmek için iki mekanizması vardır.
SUBACK'te granted QoS. Bir client subscribe olduğunda broker, her filtre için verilen QoS'u içeren bir SUBACK ile yanıt verir. İstenenden daha düşük bir seviye verebilir. MQTT 3.1.1'de dönüş kodları 0, 1, 2 veya hata için 0x80'dir; MQTT 5'te ise 0x00, 0x01 ve 0x02'nin sırasıyla verilen QoS 0, 1 ve 2 anlamına geldiği reason code'lardır. İyi yazılmış bir client, isteğinin karşılandığını varsaymak yerine bu değeri kontrol eder.
CONNACK'te Maximum QoS (MQTT 5). QoS 2'yi veya QoS 1 ve 2'yi desteklemeyen bir MQTT 5 broker, CONNACK'e bir Maximum QoS property'si ekler. Property yoksa QoS 2 desteklenir. Ardından bildirilen maksimumun üzerinde publish eden bir client protokolü ihlal etmiş olur ve broker onu 0x9B (QoS not supported) reason code'u ile bağlantıdan düşürür. MQTT 3.1.1'de böyle bir property yoktur; bu yüzden client'lar bunu zor yoldan öğrenir.
Broker'ların QoS'u sınırlamak için haklı nedenleri vardır: QoS 2 daha fazla saklanan durum ve her adımda mesaj başına dört paket gerektirir; bu da paylaşılan, çok kiracılı altyapıda hızla birikir.
MQTT Maksimum QoS'u Herkese Açık Bir Broker'da Test Etmek
broker.connectmq.com adresindeki herkese açık MQTT test broker'ı QoS 0 ile 2 arasını destekler; bu yüzden publish/subscribe kombinasyonunun neden olduğu düşüşleri görmek için iyi bir yerdir. -d bayrağı, Mosquitto araçlarının SUBACK'teki granted QoS dahil protokol paketlerini yazdırmasını sağlar.
Terminal 1, QoS 1 isteyerek subscribe olun:
mosquitto_sub -d -h broker.connectmq.com -p 1883 -i mq-sub-u3x7 -q 1 \
-t 'connectmq/demo/u3x7/#' -F 'qos=%q %t %p'
Debug çıktısında Client mq-sub-u3x7 received SUBACK ve ardından Subscribed (mid: 1): 1 gibi bir satır arayın. Sondaki sayı granted QoS'tur.
Terminal 2, her seviyede publish edin:
for q in 0 1 2; do
mosquitto_pub -h broker.connectmq.com -p 1883 -i mq-pub-u3x7 -q $q \
-t connectmq/demo/u3x7/test -m "published at qos $q"
done
Terminal 1 qos=0, qos=1 ve qos=1 yazdırır. QoS 2 publish, bu subscriber'a giderken 1'e düşürüldü, çünkü subscription bunu istedi. Subscriber'ı -q 2 ile yeniden başlatın; üçüncü satır qos=2 olur.
Granted ve Maximum QoS'u Kodda Kontrol Etmek
Bu paho-mqtt 2.x betiği MQTT 5 ile bağlanır, varsa broker'ın bildirdiği Maximum QoS'u yazdırır, QoS 2 ile subscribe olur ve kendisine ne verildiğini yazdırır:
import uuid
import paho.mqtt.client as mqtt
BROKER = "broker.connectmq.com"
TOPIC = "connectmq/demo/u3x7/check"
def on_connect(client, userdata, flags, reason_code, properties):
max_qos = getattr(properties, "MaximumQoS", None)
if max_qos is None:
print("CONNACK: no Maximum QoS property, QoS 2 supported")
else:
print(f"CONNACK: broker maximum QoS is {max_qos}")
client.subscribe(TOPIC, qos=2)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
rc = reason_code_list[0]
if rc.is_failure:
print("subscription refused:", rc)
else:
print(f"SUBACK: requested 2, granted {rc.value}")
client.disconnect()
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"qoscheck-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.connect(BROKER, 1883, keepalive=30)
client.loop_forever()
Bir QoS seviyesine güvenmeden önce aynı betiği gerçek kimlik bilgilerinizle üretim broker'ınıza karşı çalıştırın. Saniyeler sürer ve tahmin yürütmeyi ortadan kaldırır.
Retained ve Will Mesajlarında QoS
Aynı minimum kuralı, broker'ın kendi inisiyatifiyle gönderdiği mesajlar için de geçerlidir. Retained bir mesaj publish edildiği QoS ile saklanır ve yeni bir subscriber onu bu QoS ile granted subscription QoS'undan düşük olanıyla alır. Last Will, CONNECT'te ayarlanan will QoS ile publish edilir ve her subscriber yine ikisinden düşük olanıyla alır. Broker'ın maksimum QoS'u istediğiniz will QoS'undan düşükse, bir MQTT 5 broker bağlantıyı 0x9B reason code'u ile reddedebilir; bu yüzden will QoS'u bildirilen sınır içinde tutun.
Pratik Kontrol Listesi
- Kaybolan veya tekrarlanan bir mesajın maliyetine göre her topic için QoS'a karar verin.
- O QoS ile publish edin; subscriber'lar onu yükseltemez.
- SUBACK'teki granted QoS'u kontrol edin ve istenenden düşükse loglayın.
- MQTT 5 ile CONNACK'ten Maximum QoS'u okuyun ve publish'lerinizi buna göre sınırlayın.
- Tüketicileri gerçekte aldığınız QoS'a göre tasarlayın: QoS 1 için idempotent (bkz. MQTT tekrarlanan mesajlar), QoS 0 için boşluklara toleranslı.
- Aynı client'ta farklı QoS'lu çakışan subscription'lardan kaçının.
QoS Sorunlarını Gidermek
Client, publish ettikten hemen sonra bağlantıdan düşürüldü. Reason code 0x9B ise broker'ın maksimumunun üzerinde publish ettiniz. QoS'u düşürün veya onu destekleyen bir plana ya da broker'a geçin. Kodların tam listesi MQTT reason code'ları yazısında.
Subscriber, QoS 1 ile subscribe olmasına rağmen QoS 0 alıyor. Publisher QoS 0 kullanıyor. Sorunu kaynağında düzeltin.
Kütüphane başarı bildiriyor ama mesajlar kayboluyor. Bazı kütüphaneler granted QoS'u yok sayar. Yukarıdaki betikte olduğu gibi SUBACK'i kendiniz kontrol edin.
QoS 2 yavaş. Her mesaj, her adımda dört paket gerektirir. Yüksek hızlı telemetri için tekilleştirmeli QoS 1 genellikle daha iyi verim sağlar.
Normatif kurallar, OASIS MQTT 5.0 spesifikasyonunun SUBACK ve CONNACK property'leri bölümlerinde yer alır.
ConnectMQ Planlarında QoS Sınırları
ConnectMQ, plan bazında QoS konusunda açıktır. Ücretsiz Serverless planı QoS 1'e kadar destekler; ücretli Serverless planı QoS 2'yi daha büyük mesajlar ve shared subscription'larla birlikte ekler; Dedicated, BYOC ve Self Managed Enterprise seçenekleri ise size izole bir küme sunar. Herkese açık test broker'ı deneyler için QoS 0 ile 2 arasına izin verir. Bağlantınızın ne bildirdiğini doğrulamak için kontrol betiğini ConnectMQ kimlik bilgilerinizle çalıştırın. Sağlayıcıları karşılaştırıyorsanız tam yönetilen MQTT hizmeti yazımız ve MQTT eğitimi iyi sonraki okumalardır.
ConnectMQ ile Başlayın
app.connectmq.com adresinde, kredi kartı gerekmeden Serverless planında ücretsiz bir broker oluşturun. QoS 0 ve 1 ile başlayın, bulut MQTT broker iş yükünüz tam olarak bir kez teslim gerektirdiğinde QoS 2 için ücretli plana geçin.
Sık Sorulan Sorular
MQTT'de efektif QoS nedir?
Bir mesajı subscriber'a teslim etmek için kullanılan QoS'tur: publish QoS'u ile subscription'ın granted QoS'undan düşük olanı.
Bir subscriber, publisher'ın kullandığından daha yüksek bir QoS alabilir mi?
Hayır. QoS 0 ile publish edilen bir mesaj, subscription ne olursa olsun her zaman QoS 0 ile teslim edilir.
Broker'ın maksimum QoS'unu nasıl öğrenirim?
MQTT 5'te CONNACK'teki Maximum QoS property'sini okuyun; yoksa QoS 2 desteklenir. MQTT 3.1.1'de SUBACK'teki granted QoS'u kontrol edin.
Maksimum QoS'un üzerinde publish edersem ne olur?
Bir MQTT 5 broker, client'ı 0x9B (QoS not supported) reason code'u ile bağlantıdan düşürür.



