Temeller

MQTT QoS Seviyeleri: QoS 0, 1 ve 2 Açıklaması

MQTT QoS rehberi: QoS 0, 1 ve 2 paket paket nasıl çalışır, düşürme kuralı ne demektir, oturumlar teslimatı nasıl etkiler ve hangi seviyeyi seçmelisiniz?

Güncellendi · 7 dk okuma

MQTT QoS (Quality of Service, hizmet kalitesi), protokolün bir mesajı teslim etmek için ne kadar çaba göstereceğini belirler. Üç QoS seviyesi vardır — 0, 1 ve 2 — ve her biri daha güçlü bir garanti karşılığında ek onay (acknowledgement) paketleri getirir. Doğru seviyeyi seçmek, bir MQTT sistemindeki en önemli tasarım kararlarından biridir: çok düşük seçerseniz veri kaybedersiniz, çok yüksek seçerseniz bant genişliği ve gecikme israf edersiniz.

Bir bakışta QoS seviyeleri

QoSGarantiAtlama başına paketKopya mümkün mü?
0En fazla bir kez (at most once)1 (PUBLISH)Hayır — ancak mesajlar kaybolabilir
1En az bir kez (at least once)2 (PUBLISH, PUBACK)Evet
2Tam olarak bir kez (exactly once)4 (PUBLISH, PUBREC, PUBREL, PUBCOMP)Hayır

Önemli bir ayrıntı: QoS her atlama (hop) için ayrı belirlenir. Publisher’ın QoS’u broker’a giden yolu, aboneliğin QoS’u ise broker’dan her bir subscriber’a giden yolu belirler.

QoS 0 — en fazla bir kez

Gönderen PUBLISH paketini bir kez iletir ve unutur. Ne onay vardır ne de packet identifier. Mesaj yoldayken TCP bağlantısı koparsa mesaj kaybolur.

QoS 0 akışı
Sender                     Receiver
  | ---- PUBLISH (QoS 0) ---> |
  |                           |  (no reply)

QoS 0 en ucuz seçenektir ve bir sonraki mesajın kaybolanın yerini aldığı yüksek frekanslı telemetri için — her saniye bir sıcaklık ölçümü, bir GPS konumu, bir heartbeat — gayet uygundur. Canlı bir bağlantıda TCP’nin bozulmaya ve sıra karışmasına karşı yine koruma sağladığını unutmayın; asıl risk, bağlantılar koptuğunda mesaj kaybıdır.

QoS 1 — en az bir kez

Gönderen bir packet identifier atar, mesajı saklar ve aynı identifier’a sahip bir PUBACK bekler. Onay gelene kadar mesaj “inflight” (yolda) kabul edilir. Bağlantı daha önce koparsa gönderen, oturum devam ettiğinde mesajı DUP bayrağı set edilmiş olarak yeniden iletir.

QoS 1 akışı
Sender                          Receiver
  | ---- PUBLISH (QoS 1, id=7) ---> |  store + deliver
  | <--------- PUBACK (id=7) ------ |
  |  delete stored message          |

Püf noktası şu: PUBACK kaybolursa alıcı mesajı zaten işlemiştir ve yeniden iletimde onu tekrar alır. Dolayısıyla QoS 1 teslimatı garanti eder ama kopyalara izin verir. Çoğu uygulama için doğru denge budur — handler’larınızı idempotent yapın (örneğin payload’a bir mesaj ID’si veya zaman damgası ekleyerek) ve düşük ek yükle güvenilirlik elde edin.

QoS 2 — tam olarak bir kez

QoS 2, hiçbir tarafın mesajı iki kez teslim edememesi için dört adımlı bir el sıkışma kullanır:

QoS 2 akışı
Sender                          Receiver
  | ---- PUBLISH (QoS 2, id=9) ---> |  store id=9, (deliver)
  | <--------- PUBREC (id=9) ------ |
  | ---------- PUBREL (id=9) -----> |  release id=9
  | <--------- PUBCOMP (id=9) ----- |
  |  done                           |
  1. PUBLISH — gönderen mesajı iletir ve bir kopyasını saklar.
  2. PUBREC — alıcı mesajı aldığını onaylar ve packet identifier’ı kaydeder. Bu identifier ile yeniden iletilen her PUBLISH kopya olarak tanınır ve tekrar teslim edilmez.
  3. PUBREL — gönderen mesajı siler ve alıcıya identifier’ı serbest bırakabileceğini bildirir.
  4. PUBCOMP — alıcı onaylar; identifier yeniden kullanılabilir.

Bunun maliyeti, atlama başına iki gidiş-dönüş ve her iki tarafta tutulan durum bilgisidir. QoS 2, kopyanın gerçekten zararlı olduğu ve uygulamada filtrelenemediği mesajlar için mantıklıdır — örneğin faturalama olayları veya tek seferlik aktüatör komutları. Pratikte birçok ekip bunun yerine QoS 1 ve tekilleştirme (deduplication) kullanır.

Düşürme kuralı: efektif QoS

Subscriber, SUBSCRIBE paketinde bir maksimum QoS talep eder ve broker verilen QoS’u SUBACK içinde döndürür. Ardından her mesaj, publish QoS’u ile verilen abonelik QoS’undan düşük olanıyla teslim edilir:

Publish QoS’uAbonelik QoS’uTeslim QoS’u
QoS 2QoS 0QoS 0
QoS 1QoS 2QoS 1
QoS 0QoS 1QoS 0
QoS 2QoS 2QoS 2

Broker’lar QoS’u sınırlayabilir de: MQTT 5’te bir broker CONNACK içinde Maximum QoS bildirebilir, bazı broker’lar veya bulut servisleri ise QoS 2’yi hiç desteklemez. İstediğinizi aldığınızı varsaymak yerine SUBACK içindeki verilen QoS’u her zaman kontrol edin.

QoS ve oturumlar: çevrimdışıyken ne olur?

QoS mesajları yalnızca bir oturum (session) varken korur. Clean session ile (3.1.1’de cleanSession=true, MQTT 5’te session expiry 0 ile cleanStart=true) broker, client bağlantıyı keser kesmez abonelikleri ve bekleyen mesajları siler — yani siz çevrimdışıyken publish edilen QoS 1 ve 2 mesajları size hiçbir zaman teslim edilmez.

Client çevrimdışıyken gelen mesajları almak için şu üçüne birden ihtiyacınız var:

  • sabit ve benzersiz bir client ID,
  • kalıcı bir oturum (cleanSession=false veya MQTT 5’te sıfırdan farklı bir Session Expiry Interval),
  • QoS 1 veya 2 ile yapılmış bir abonelik ve QoS 1 veya 2 ile publish edilen mesajlar.

Ayrıca onaylanmamış mesajların yeniden iletiminin, oturum yeniden bağlandıktan sonra devam ettiğinde gerçekleştiğini unutmayın — ne 3.1.1 ne de 5.0 canlı bir bağlantıda yeniden göndermeyi şart koşar, çünkü orada kaybı zaten TCP ele alır.

QoS’u pratikte test etmek

QoS’u Mosquitto CLI ile iş başında izleyebilirsiniz. -d bayrağı her paketi yazdırır, böylece PUBREC/PUBREL/PUBCOMP paketlerinin geçişini görebilirsiniz:

bash
# subscriber with a persistent session (-c) and fixed client ID
mosquitto_sub -h broker.emqx.io -t 'testmqtt/qos-demo/#' -q 2 -c -i qos-demo-sub -d

# publish at QoS 2
mosquitto_pub -h broker.emqx.io -t 'testmqtt/qos-demo/order' -m 'order-1001' -q 2 -d

Subscriber’ı durdurun, birkaç QoS 1 mesajı publish edin, sonra aynı client ID ile yeniden başlatın: kuyruktaki mesajlar gelmelidir. Tarayıcıda online MQTT client, her abonelik ve her publish için QoS seçmenize olanak tanır. Daha fazla test senaryosu için MQTT broker nasıl test edilir yazısına bakın.

Online MQTT istemcisinde deneyin

QoS seviyesi seçmek

  • QoS 0 — yalnızca en son değerin önemli olduğu sık sensör verileri, konumlar, metrikler.
  • QoS 1 — olaylar, alarmlar ve komutlar için mantıklı varsayılan; idempotent handler’larla birlikte kullanın.
  • QoS 2 — kopyaların maliyetli olduğu ve sonraki aşamalarda tekilleştirilemediği nadir durumlar.

QoS, retained mesajlar ve Last Will ile el ele çalışır; protokolde yeniyseniz MQTT nedir yazısıyla başlayın.

Sıkça sorulan sorular

Hangi MQTT QoS seviyesini kullanmalıyım?

Kaybolan bir ölçümün önemli olmadığı sık telemetri için QoS 0, çoğu olay ve komut için QoS 1 (handler’larınızı idempotent yapın), QoS 2’yi ise yalnızca kopyaların gerçekten zararlı olduğu ve uygulamada tekilleştirme yapamadığınız durumlarda kullanın.

Bir QoS 1 mesajını neden iki kez aldım?

QoS 1 “en az bir kez” teslimattır. Onay kaybolursa (genellikle bağlantı koptuğu için) gönderen, yeniden bağlandıktan sonra mesajı DUP bayrağıyla tekrar iletir; bu nedenle alıcı mesajı iki kez görebilir.

QoS 2 uçtan uca “tam olarak bir kez” teslimatı garanti eder mi?

Hayır. QoS her atlamaya ayrı ayrı uygulanır: publisher’dan broker’a ve broker’dan subscriber’a. Subscriber, publish QoS’u ile abonelik QoS’undan düşük olanını alır; çevrimdışı client’lar için mesajlar ise yalnızca kalıcı bir oturumları varsa saklanır.