MQTT Temelleri

MQTT Client'ınız Neden Sürekli Bağlantıyı Kesiyor (ve Nasıl Düzeltilir)

Yeniden bağlanma döngüleri en yaygın MQTT sorunlarından biridir. Yinelenen client ID'lerden keep alive zaman aşımlarına ve büyük paketlere kadar beş olağan nedeni öğrenin ve sizinkini tam olarak belirleyen bir teşhis akışını izleyin.

MQTT client'ının neden sürekli bağlantıyı kestiğini göstermek için tekrar tekrar düşüp yeniden bağlanan bir cihazın grafiği
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 client'ınız sürekli bağlantıyı kesiyorsa neden neredeyse her zaman beş şeyden biridir: aynı client ID'yi paylaşan iki client, bir keep alive zaman aşımı, boştaki bağlantıları sessizce düşüren bir ağ, broker'ın kabul etmediği bir paket veya bir plan ya da hız sınırı. Bu rehber, her birini belirtilerden ve loglardan nasıl tanıyacağınızı açıklıyor ve sizi çözüme hızla ulaştıran bir teşhis akışını adım adım anlatıyor.

Bağlantı Kopma Düzeniyle Başlayın

Herhangi bir ayarı değiştirmeden önce bağlantı kopmalarının nasıl gerçekleştiğini gözlemleyin. Zamanlama size çok şey söyler:

Düzen En olası neden
İki cihaz birkaç saniyede bir sırayla bağlantıyı kaybediyor Yinelenen client ID
Düzenli aralıklarla, yaklaşık 1,5 x keep alive sürede kopma Keep alive'a hizmet edilmiyor
Birkaç dakikalık boşta kalmadan sonra, yalnızca belirli ağlarda kopma NAT veya güvenlik duvarı boşta kalma zaman aşımı
Belirli bir mesajı publish ettikten hemen sonra kopma Paket çok büyük veya geçersiz topic
Trafik ani yükseldiğinde kopma Hız sınırı veya kota
Her bağlantıdan hemen sonra kopma Yetkilendirme veya subscription hatası

Ayrıca bağlantıyı hangi tarafın kapattığını da öğrenin. MQTT 5'te broker tarafından başlatılan bir kapatma, bir DISCONNECT paketi ve bir reason code ile gelir. MQTT 3.1.1'de broker yalnızca soketi kapatır. Mümkünse hata ayıklarken client'ı MQTT 5'e geçirin; reason code çoğu zaman soruyu anında yanıtlar. MQTT reason code'ları referansı hepsini listeler.

Neden 1: Yinelenen Client ID'ler

MQTT spesifikasyonu, bir client zaten bağlı olan bir client ID ile bağlanırsa broker'ın mevcut client'ın bağlantısını kesmesi gerektiğini söyler. Her iki client'ta da otomatik yeniden bağlanma etkinse birbirlerini sonsuza kadar düşürürler. MQTT 5'te kaybeden client 0x8E Session taken over reason code'unu alır.

Bu, düşündüğünüzden daha sık olur:

  • Koda gömülü bir client ID içeren firmware birden fazla cihaza yüklenmiştir.
  • Bir servis aynı yapılandırmayla iki replikaya ölçeklenmiştir.
  • Bir geliştirici aynı betiği iki terminalde çalıştırıyordur.
  • Cihazınızın kullandığı ID ile açık bırakılmış bir masaüstü MQTT aracı vardır.

Çözüm: client ID'leri MAC adresi, seri numarası veya host adı gibi benzersiz bir şeyden türetin ve bir ID'yi asla süreçler arasında paylaşmayın. MQTT client ID rehberi adlandırma desenlerini ele alır. Kimlik bilgileriyle birlikte client ID veren yönetilen broker'larda, verilen her ID için tek bir bağlantı çalıştırın.

Neden 2: Keep Alive Zaman Aşımları

Keep alive, client'ın verdiği bir sözdür: "en az N saniyede bir benden haber alacaksın". Broker bu aralığın 1,5 katı süre boyunca hiçbir şey almazsa bağlantıyı kapatır; MQTT 5'te 0x8D Keep Alive timeout nedeniyle. Client, gönderecek başka bir şeyi olmadığında PINGREQ gönderir, ancak yalnızca ağ döngüsü çalışıyorsa.

Bunu bozmanın yaygın yolları:

  • MQTT döngüsünü çalıştıran aynı thread'de time.sleep(120) veya yavaş bir HTTP isteği gibi uzun süre bloklayan bir fonksiyon çağırmak.
  • Arduino'da mqtt.loop() çağrısını sık yapmayı unutmak veya dakikalarca delay() kullanmak.
  • Yüksek gecikmeli bir hücresel bağlantıda keep alive'ı 5 saniye gibi çok kısa ayarlamak.
  • Temiz bir bağlantı kesme olmadan keep alive aralığından uzun deep-sleep döngüleri.

Çözüm: ağ döngüsünü bir arka plan thread'inde çalıştırın (Paho'da loop_start(); MQTT.js bunu otomatik yapar), bloklayan işleri o thread'den uzak tutun ve çoğu kurulum için 30 ile 120 saniye arasında bir keep alive seçin. Keep alive aralığı rehberi bunun nasıl ayarlanacağını açıklar.

Neden 3: NAT ve Güvenlik Duvarı Boşta Kalma Zaman Aşımları

Mobil ağlar, ev router'ları ve kurumsal güvenlik duvarları TCP bağlantılarını takip eder ve belirli bir hareketsizlik süresinden sonra onları sessizce düşürür. Ne client'a ne de broker'a haber verilir. Client sorunu ancak bir sonraki gönderim denemesinde, broker ise yalnızca keep alive süresi dolduğunda fark eder.

Belirgin işaret, kopmaların hücresel ağda veya belirli bir sahada yaşanması ama geliştirme ağınızda yaşanmamasıdır. Çözüm: keep alive'ı ağın boşta kalma zaman aşımından düşük ayarlayın; böylece PINGREQ trafiği eşlemeyi canlı tutar. Bir operatör boştaki bağlantıları birkaç dakika sonra düşürüyorsa, 60 saniyelik bir keep alive makul bir başlangıç noktasıdır.

Neden 4: Çok Büyük veya Geçersiz Paketler

Broker'lar kabul edemedikleri bir paket aldıklarında bağlantıyı kapatır. Tipik tetikleyiciler:

  • Broker'ın maksimum mesaj boyutunun üzerinde payload. MQTT 5 client'ları 0x95 Packet too large görür; 3.1.1 client'ları ise yalnızca bağlantıyı kaybeder. Bkz. MQTT mesaj boyutu sınırı rehberi.
  • + veya # içeren bir topic'e publish etmek. Wildcard'lar yalnızca subscription'larda geçerlidir.
  • Topic adında geçersiz UTF-8; binary veriyle string birleştirme sonucu oluşur.
  • MQTT 5'te yeniden bağlantıdan sonra topic alias'ın hatalı kullanımı.

Çözüm: her publish öncesinde topic'i ve payload boyutunu loglayın ve kopmanın belirli bir mesajın ardından gelip gelmediğini kontrol edin. Aynı büyük mesaj çoğu zaman yeniden bağlantıdan sonra tekrar denenir ve bu da bir döngü oluşturur.

Neden 5: Hız Sınırları ve Kotalar

Paylaşılan ve yönetilen broker'lar kendilerini sınırlarla korur. İzin verilenden hızlı publish etmek, planınızın izin verdiğinden fazla bağlantı açmak veya subscription sayısını aşmak retlere veya bağlantı kopmalarına yol açabilir. MQTT 5'te 0x96 Message rate too high ve 0x97 Quota exceeded kodlarına bakın.

broker.connectmq.com adresindeki herkese açık MQTT test broker'ında her client saniyede 10 mesaj, 10 subscription ve mesaj başına 64 KB ile sınırlıdır. Özel broker'larda ise plan bazında sınırlar vardır; örneğin ücretsiz Serverless planı en fazla 25 bağlantıya ve 256 KB mesajlara izin verir.

İşe Yarayan Bir Teşhis Akışı

  1. Client loglamasını etkinleştirin. Paho'da client.enable_logger(); Mosquitto araçlarında -d; MQTT.js'te DEBUG=mqttjs* ayarlayın.
  2. MQTT 5 ile bağlanın ve her DISCONNECT'ten gelen reason code ile Reason String'i loglayın.
  3. Bağlanma ve kopma zaman damgalarını kaydedin ve aralığı keep alive değerinizle karşılaştırın.
  4. Broker tarafını kontrol edin. Broker'daki client ID'nin bağlantı durumuna ve aynı anda aynı ID ile başka bir bağlantının görünüp görünmediğine bakın.
  5. Minimal bir client ile yeniden üretin. Aynı ağda aynı kimlik bilgileriyle mosquitto_sub çalıştırın. Bağlı kalıyorsa sorun uygulamanızdadır.
  6. Her seferinde tek bir şeyi değiştirin: client ID, keep alive, payload boyutu, publish hızı.

İşte 1 ile 3 arasındaki adımlar için ihtiyacınız olan her şeyi loglayan minimal bir Python client'ı:

import time
import paho.mqtt.client as mqtt

started = time.time()

def ts():
    return f"[{time.time() - started:7.1f}s]"

def on_connect(client, userdata, flags, reason_code, properties):
    print(ts(), "CONNECT", reason_code, "session_present:", flags.session_present)
    client.subscribe("connectmq/demo/5a3c/#", qos=1)

def on_disconnect(client, userdata, flags, reason_code, properties):
    reason = getattr(properties, "ReasonString", "") if properties else ""
    print(ts(), "DISCONNECT", reason_code, f"(0x{reason_code.value:02X})", reason)

client = mqtt.Client(
    mqtt.CallbackAPIVersion.VERSION2,
    client_id="disconnect-debug-5a3c",
    protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.on_disconnect = on_disconnect
client.reconnect_delay_set(min_delay=1, max_delay=60)
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_forever(retry_first_connection=True)

Bir client'ı broker'ın gözünden başka bir terminalden izlemek için onun bağlantı durumu topic'ine subscribe olun:

mosquitto_sub -h broker.connectmq.com -p 8883 --capath /etc/ssl/certs \
  -u YOUR_USERNAME -P YOUR_PASSWORD -i YOUR_MONITOR_CLIENT_ID \
  -t '$SYS/broker/connection/YOUR_CLIENT_ID/state' -v

Shell'in $SYS ifadesini genişletmemesi için topic'i tek tırnak içine alın. MQTT $SYS topic'leri rehberi, bu yolla başka neleri izleyebileceğinizi açıklar. Broker client ID'leri kimlik bilgilerine bağladığı için izleme bağlantısının kendi geçerli client ID'sine ihtiyacı vardır; hızlı bir bakış için portaldaki tarayıcı içi MQTT istemcisi kolay bir alternatiftir.

İşleri Daha Kötüleştirmeyen Yeniden Bağlanma Mantığı

Otomatik yeniden bağlanma şarttır, ancak özensiz bir uygulama tek bir sorunu çok sayıda soruna dönüştürür:

  • Jitter'lı üstel backoff kullanın; böylece bir kesintiden sonra filo aynı anda yeniden bağlanmaz.
  • Yetkilendirme hatalarında yeniden denemeyin. 0x86 ve 0x87 kodları kendiliğinden düzelmez ve tekrarlanan başarısız girişler IP'nizin engellenmesine yol açabilir.
  • Kalıcı bir oturuma güvenmiyorsanız başlangıçta bir kez değil, on_connect içinde yeniden subscribe olun.
  • Bir Last Will kullanın; böylece diğer sistemler bir cihaz beklenmedik şekilde düştüğünde haberdar olur. Bkz. MQTT Last Will and Testament.

ConnectMQ ile Bağlantı Kopmalarını Teşhis Edin

ConnectMQ, kendi barındırdığınız kurulumlarda çoğu zaman eksik olan broker tarafı görünürlüğü sağlar. Portal dashboard'u ve cihazlar görünümü hangi client'ların bağlı olduğunu gösterir, canlı topic gezgini ne publish ettiklerini gösterir ve $SYS/broker/connection/{clientId}/state topic'i kendi araçlarınızın bağlantı değişikliklerini izlemesini sağlar. MQTT 5 client'ları kota ve protokol ihlalleri için reason code alır; böylece tahmin yürütmek yerine bir bağlantının neden koptuğunu görebilirsiniz. Bir bağlantının ömrü boyunca bir MQTT broker'ın ne yaptığına dair arka plan için açıklayıcı yazımıza, protokolün tamamı için MQTT eğitimine bakın.

ConnectMQ ile Kararlı Bağlantılar Elde Edin

Tam yönetilen bir MQTT hizmeti, broker'ın çalışır durumda kalmasını yapılacaklar listenizden çıkarır ve client davranışına odaklanmanızı sağlar. app.connectmq.com adresinde, kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun ve ürününüzü yayınlamadan önce yeniden bağlanma mantığınızı gerçek sınırlara karşı test edin. Seçenekleri bulut MQTT broker rehberimizde karşılaştırın.

Sık Sorulan Sorular

MQTT client'ım neden birkaç saniyede bir bağlantıyı kesiyor?

En yaygın neden, aynı client ID'yi kullanan başka bir client'tır. Her bağlantı diğerini düşürür ve ikisi de otomatik olarak yeniden bağlanır. Her client'a benzersiz bir ID verin.

Hangi keep alive değerini kullanmalıyım?

Çoğu kurulum için 30 ile 120 saniye arası uygundur. Ağınızın boşta kalma zaman aşımının altında bir değer kullanın ve PINGREQ'in gerçekten gönderilmesi için client'ın ağ döngüsünün sürekli çalıştığından emin olun.

Bağlantıyı broker'ın mı yoksa client'ın mı kapattığını nasıl anlarım?

MQTT 5 ile bağlanın. Bağlantıyı broker kapattıysa client reason code'lu bir DISCONNECT paketi alır; soket yalnızca koptuysa client reason code olmadan bir ağ hatası bildirir.

Büyük bir mesaj bağlantı kopmalarına neden olabilir mi?

Evet. Bir paket broker'ın maksimum boyutunu aşarsa broker bağlantıyı kapatır ve client yeniden bağlandıktan sonra aynı mesajı tekrar denerse bağlantı yeniden kopar. Payload boyutlarını broker'ınızın sınırına göre kontrol edin.

İ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

MQTT vs CoAP: TCP Üzerinde Pub/Sub ve UDP Üzerinde İstek/Yanıt

MQTT ve CoAP'nin ikisi de kısıtlı IoT cihazlarını hedefler ama zıt yaklaşımlar benimser: TCP üzerinde broker tabanlı pub/sub ve UDP üzerinde RESTful istek/yanıt. İşte nasıl karşılaştırıldıkları ve hangisinin ne zaman kullanılacağı.

8 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.