MQTT Temelleri

MQTT Will Delay Interval: Yanlış Çevrimdışı Uyarılarından Nasıl Kaçınılır?

Wi-Fi bağlantısı üç saniyeliğine kopan bir cihaz, nöbetçi mühendisinizi uyandırmamalı. MQTT 5'in will delay interval özelliği, Last Will mesajını hızlı bir yeniden bağlanmaya yetecek kadar bekletir.

Bir IoT cihazı hızla yeniden bağlanırken çevrimdışı Last Will mesajını bekleten zamanlayıcıyı gösteren MQTT will delay interval çizimi
Bunu kendi MQTT broker’ınızda çalıştırınFree planla özel, yönetilen bir MQTT broker alın ve hazır kod örnekleriyle başlayın.
Ücretsiz deneyin Kod örnekleri Kart gerekmez

MQTT will delay interval, broker'a bir istemcinin Last Will mesajını publish etmeden önce belirli bir saniye beklemesini ve istemci zamanında yeniden bağlanırsa mesajı tamamen iptal etmesini söyleyen bir MQTT 5 özelliğidir. Bu yazıda kısa ağ kesintilerinin neden olduğu gürültülü çevrimdışı uyarılarını nasıl bastırdığını, session expiry ile nasıl etkileştiğini ve mosquitto, Python ve Node.js'te nasıl yapılandırılacağını göreceksiniz.

Sorun: Sürekli Yanıp Sönen Çevrimdışı Uyarıları

Last Will and Testament, MQTT'nin bir istemcinin ortadan kaybolduğunu duyurmak için sunduğu yerleşik yöntemdir. İstemci, bağlanırken bir will mesajı kaydeder (genellikle bir durum topic'inde retained bir offline) ve bağlantı düzgün bir DISCONNECT olmadan sona ererse broker bu mesajı publish eder.

MQTT 3.1.1'de will, broker arızayı tespit eder etmez publish edilir. Gerçek ağlarda bu gürültülüdür:

  • Bir Wi-Fi erişim noktası cihazı başka bir AP'ye aktarır ve TCP bağlantısı sıfırlanır.
  • Bir hücresel modem yeniden müzakere yapar ve cihaz saniyeler içinde geri döner.
  • Bir gateway, yapılandırma değişikliğinden sonra MQTT sürecini yeniden başlatır.

Her durum, birkaç an sonra online ile takip edilen bir offline mesajı üretir. Dashboard'lar yanıp söner, alarm kuralları tetiklenir ve operatörler uyarıları görmezden gelmeyi öğrenir; bu da hiç uyarı olmamasından daha kötüdür.

MQTT Will Delay Interval Nasıl Çalışır?

MQTT 5, CONNECT içindeki will mesajına eklenen, saniye cinsinden dört baytlık bir özellik olan Will Delay Interval'ı getirir. Ağ bağlantısı anormal şekilde kapandığında:

  1. Broker, will delay interval süresi için bir zamanlayıcı başlatır.
  2. Aynı istemci zamanlayıcı dolmadan aynı oturuma yeniden bağlanırsa will publish edilmez.
  3. Önce zamanlayıcı dolarsa will her zamanki gibi publish edilir.
  4. Önce oturum sona ererse (session expiry interval dolduğu için) will o anda publish edilir.

Varsayılan değer 0'dır ve 3.1.1'deki anında yayınlama davranışını yeniden üretir.

Herkesin Gözden Kaçırdığı Kural: Session Expiry

Will, gecikme süresi geçtiğinde veya oturum sona erdiğinde, hangisi önce gelirse publish edilir. İstemci 0 session expiry interval ile bağlanırsa oturum bağlantının kapandığı anda sona erer; dolayısıyla will hemen gönderilir ve gecikmenizin hiçbir etkisi olmaz.

Will delay Session expiry Sonuç
0 herhangi Anormal bağlantı kesilmesinde anında will
30 sn 0 Anında will (önce oturum sona erdi)
30 sn 60 sn İstemci yeniden bağlanmazsa 30 sn sonra will
30 sn 10 sn 10 sn sonra will (önce oturum sona erdi)
300 sn 3600 sn İstemci yeniden bağlanmazsa 5 dakika sonra will

Bu nedenle will delay kullanmak için her zaman en az gecikme kadar uzun bir session expiry interval ayarlayın ve broker'ın yeni bağlantıyı aynı oturum olarak değerlendirmesi için Clean Start false olarak yeniden bağlanın. Ayrıntılar MQTT 5 clean start ve session expiry interval yazısında.

Keep Alive Toplam Süreye Eklenir

Zamanlayıcı ancak broker bağlantının gittiğini fark ettiğinde başlar. Bir cihazın gücü kesilirse tespit, keep alive süresinin 1,5 katına kadar sürer. 60 saniyelik keep alive ve 30 saniyelik will delay ile çevrimdışı mesajına kadar geçen en kötü durum süresi yaklaşık iki dakikadır. İkisini birlikte planlayın; bkz. MQTT keep alive süresini seçmek.

Will Delay Değerini Seçmek

Normal yeniden bağlanma sürenizi kapsayan en kısa gecikmeyi seçin.

  • Hızlı yeniden bağlanma mantığına sahip Wi-Fi cihazları: 10 ila 30 saniye.
  • Hücresel cihazlar: 30 ila 120 saniye; modemin yeniden kaydı daha yavaştır.
  • Güncellemeler sırasında servislerini yeniden başlatan gateway'ler: tipik bir yeniden başlatmadan biraz daha uzun.
  • Güvenlik açısından kritik ekipmanlar: kısa tutun veya 0 yapın. Gecikmiş bir alarm, yanlış bir alarmdan daha pahalıya mal olabilir.

Pratik bir test: gerçek çalışmanın bir haftası boyunca bağlantı kesilmesi ile yeniden bağlanma arasındaki süreyi loglayın ve bu aralıkların büyük kısmının hemen üzerinde bir değer seçin.

Will Delay'i Kodda Yapılandırmak

Tüm örnekler broker.connectmq.com adresindeki herkese açık MQTT test broker'ını kullanır. w3d8 değerini kendi rastgele dizenizle değiştirin ve herkese açık alanın herkes tarafından okunabildiğini unutmayın.

Simüle Edilmiş Cihaz Olarak mosquitto_sub

mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
  -i willdelay-dev-w3d8 -c -x 120 \
  --will-topic 'connectmq/demo/w3d8/status' \
  --will-payload 'offline' --will-qos 1 --will-retain \
  -D will will-delay-interval 30 \
  -t 'connectmq/demo/w3d8/cmd'

Başka bir terminalde durum topic'ini izleyin:

mosquitto_sub -h broker.connectmq.com -p 1883 -i willdelay-watch-w3d8 \
  -v -t 'connectmq/demo/w3d8/status'

mosquitto_sub'da Ctrl+C düzgün bir DISCONNECT gönderir ve bu hiçbir zaman will tetiklemez. Gerçek bir arızayı simüle etmek için bunun yerine süreci sonlandırın (örneğin süreç kimliğine kill -9 uygulayarak veya ağ kablosunu çekerek). Ardından iki durumu deneyin: cihaz komutunu 30 saniye içinde yeniden başlatırsanız hiçbir offline görünmez; daha uzun beklerseniz görünür.

Python (paho-mqtt 2.x)

import paho.mqtt.client as mqtt
from paho.mqtt.properties import Properties
from paho.mqtt.packettypes import PacketTypes

STATUS = "connectmq/demo/w3d8/status"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id="willdelay-py-w3d8",
                     protocol=mqtt.MQTTv5)

will_props = Properties(PacketTypes.WILLMESSAGE)
will_props.WillDelayInterval = 30          # saniye
client.will_set(STATUS, payload="offline", qos=1, retain=True,
                properties=will_props)

def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    # Çevrimiçi olduğumuzu duyur (retained "offline" mesajının üzerine yazar)
    client.publish(STATUS, "online", qos=1, retain=True)

client.on_connect = on_connect

connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 120  # will delay'den büyük veya eşit olmalı

client.connect("broker.connectmq.com", 1883, keepalive=30,
               clean_start=False, properties=connect_props)
client.loop_forever()

Node.js (MQTT.js v5)

const mqtt = require("mqtt");
const STATUS = "connectmq/demo/w3d8/status";

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "willdelay-node-w3d8",
  protocolVersion: 5,
  clean: false,
  keepalive: 30,
  properties: { sessionExpiryInterval: 120 },
  will: {
    topic: STATUS,
    payload: Buffer.from("offline"),
    qos: 1,
    retain: true,
    properties: { willDelayInterval: 30 },
  },
});

client.on("connect", () => {
  client.publish(STATUS, "online", { qos: 1, retain: true });
});

Eksiksiz Bir Çevrimiçi/Çevrimdışı Kalıbı

Will delay, tutarlı bir varlık (presence) tasarımının parçası olduğunda en iyi sonucu verir:

  1. Will delay ve buna uygun session expiry ile retained bir offline will kaydedin.
  2. Her başarılı bağlantının hemen ardından retained bir online publish edin.
  3. Planlı bir kapatmadan önce retained offline mesajını kendiniz publish edin, ardından bağlantıyı düzgün şekilde kesin.
  4. Dashboard'ların ve alarm kurallarının yalnızca retained durum topic'ini okumasını sağlayın.
  5. İsteğe bağlı olarak, operatörlerin bir cihazın neden çevrimdışı olduğunu görebilmesi için JSON payload'a bir zaman damgası veya neden ekleyin.

Diğer varlık kalıpları MQTT cihaz çevrimiçi durumu yazısında ele alınıyor. Bir ConnectMQ broker'ında, uygulama düzeyindeki durumunuz yerine broker'ın ham bağlantıya dair görünümünü yansıtan $SYS/broker/connection/{clientId}/state topic'iyle de çapraz kontrol yapabilirsiniz.

Will Delay ile Uygulamada Debounce Karşılaştırması

MQTT 5'ten önce ekipler, bu yanıp sönme sorununu tüketici tarafında debounce ile çözüyordu: bir dashboard veya uyarı servisi, bir offline mesajından sonra N saniye bekliyor ve ancak ardından online gelmezse alarm veriyordu. Bu yöntem hâlâ işe yarar, ancak her tüketicinin aynı mantığı uygulaması gerekir ve her biri farklı bir pencere seçebilir. Will delay kararı broker'a taşır; böylece her subscriber aynı, önceden filtrelenmiş durum akışını görür. Bunun bedeli, gecikmenin bağlantı anında istemci bazında ayarlanmasıdır; yani değeri değiştirmek tek bir backend servisi yerine cihaz yapılandırmasını güncellemek anlamına gelir.

Will Delay Sorunlarını Gidermek

  • Will hâlâ hemen tetikleniyor: session expiry 0 veya will delay'den kısa ya da MQTT 3.1.1 ile bağlanıyorsunuz.
  • Cihaz hızla yeniden bağlanmasına rağmen will tetikleniyor: cihaz Clean Start true ile veya farklı bir client ID ile yeniden bağlandı; dolayısıyla bu yeni bir oturumdu.
  • Will hiç tetiklenmiyor: istemci bağlantıyı düzgün şekilde kesti veya gecikme beklediğinizden uzun. Keep alive tespit süresini de eklemeyi unutmayın.
  • Yeniden bağlandıktan sonra eski offline görünüyor: retained online mesajını yalnızca ilk bağlantıda değil, her bağlantıda publish edin.

Bu kavramlarda yeni misiniz? MQTT eğitimi will'leri, oturumları ve retained mesajları en baştan açıklıyor.

ConnectMQ'da Güvenilir Cihaz Durumu Oluşturun

ConnectMQ; will özellikleri, session expiry ve retained mesajlar dahil tam MQTT 5.0 desteğine sahip yönetilen bir MQTT broker'dır. Portalı eşik tabanlı alarm kuralları ve bir alarm günlüğü de sunar; dolayısıyla protokol düzeyinde daha temiz durum verisi, bunun üzerine kurduğunuz kurallardan daha az gürültülü uyarı anlamına gelir. Kredi kartı gerektirmeden Serverless planında ücretsiz başlayın, YOUR_USERNAME, YOUR_PASSWORD ve YOUR_CLIENT_ID ile bağlanın ve will delay ayarlarınızı kendi broker'ınızda test edin.

Sık Sorulan Sorular

Varsayılan MQTT will delay interval nedir?

Varsayılan değer 0 saniyedir; yani will mesajı, tıpkı MQTT 3.1.1'de olduğu gibi broker anormal bir bağlantı kesilmesini tespit eder etmez publish edilir.

Will mesajım neden gecikmeyi yok sayıyor?

Çoğu zaman session expiry interval 0'dır veya will delay'den kısadır. Broker will'i oturum sona erdiğinde publish eder; bu nedenle oturumun en az gecikme kadar sürmesi gerekir.

Will delay MQTT 3.1.1'de mevcut mu?

Hayır. Bu bir MQTT 5 özelliğidir. MQTT 3.1.1'de bunun yerine çevrimdışı olaylarını tüketen uygulamada debounce yapmanız gerekir.

Düzgün bir bağlantı kesme will mesajını tetikler mi?

Hayır. Normal bir DISCONNECT will'i atar. MQTT 5'te bir istemci, 0x04 (Disconnect with Will Message) reason code'uyla bağlantıyı keserek will'i bilinçli olarak isteyebilir.

İlgili yazılar

MQTT'yi Kim İcat Etti? Petrol Boru Hatlarından IoT'ye Uzanan Tarih

MQTT, 1999'da IBM'den Andy Stanford-Clark ve Arcom'dan Arlen Nipper tarafından petrol boru hatlarını uydu üzerinden izlemek için icat edildi. Açık kaynağa, OASIS'e, ISO'ya ve bugünün yönetilen bulut broker'larına uzanan yolculuğunu izleyin.

7 dk okuma

MQTT Maksimum Mesaj Boyutu: Sınırlar ve Büyük Payload Stratejileri

MQTT teknik olarak 256 MB'lık bir paket taşıyabilir, ancak broker'lar, istemci kütüphaneleri ve cihazlar çok daha düşük sınırlar uygular. Gerçek sınırların nerede olduğunu, aşıldıklarında ne olduğunu ve büyük payload'ların nasıl gönderileceğini öğrenin.

6 dk okuma

Tüm yazılar →

Özel MQTT broker’ınız birkaç tık uzağınızda

Hesabınızı oluşturun, broker kimlik bilgilerinizi alın ve ilk cihazınızı bağlayın — kurulacak, yamalanacak ya da ölçeklendirilecek sunucu yok.