MQTT Temelleri

MQTT Receive Maximum: MQTT 5'te Yavaş Cihazlar için Akış Kontrolü

Receive Maximum, MQTT 5'in yerleşik akış kontrolüdür. Aynı anda uçuşta olabilecek onaylanmamış QoS 1 ve 2 mesajlarının sayısını sınırlar; böylece yavaş cihazlar yeniden bağlandıktan sonra mesaj yağmuruna boğulmaz.

Broker'dan küçük bir mikrodenetleyiciye akan mesajların sınırlı uçuş penceresini gösteren MQTT receive maximum ç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 receive maximum, karşı tarafa aynı anda kaç QoS 1 ve QoS 2 mesajının onaylanmamış şekilde "uçuşta" (in flight) olmasına razı olduğunuzu bildiren MQTT 5 ayarıdır. Bu rehberde bu akış kontrolü penceresinin her iki yönde nasıl çalıştığını, mikrodenetleyiciler ve yeniden bağlanma sonrası ani yükler için neden önemli olduğunu ve mosquitto, Python ve Node.js'te nasıl ayarlanacağını öğreneceksiniz.

Receive Maximum Hangi Sorunu Çözer?

MQTT 3.1.1'de standart bir akış kontrolü yoktu. Bir broker, QoS 1 mesajlarını TCP bağlantısının izin verdiği hızda bir istemciye gönderebiliyordu ve istemci, PUBACK gönderene kadar bunların her birini tamponlamak zorundaydı. Bu bir sunucuda işe yarar, ancak yalnızca birkaç kilobayt boş RAM'i olan bir mikrodenetleyicinin belleği tükenebilir, mesajlar düşebilir veya cihaz çökebilir. Sorun en çok, kalıcı bir oturumun kuyruktaki mesaj birikimini bir anda serbest bıraktığı yeniden bağlanmanın hemen ardından kendini gösterir.

Broker'lar ve kütüphaneler bununla başa çıkmak için kendi "max in-flight" ayarlarını icat etti, ancak bunlar müzakere edilmiyordu; dolayısıyla iki taraf da diğerinin sınırını bilmiyordu. MQTT 5 bu fikri Receive Maximum özelliği olarak standartlaştırdı.

MQTT Receive Maximum Penceresi Nasıl Çalışır?

Receive Maximum, her iki tarafın da bildirebileceği, 1 ile 65.535 arasında iki baytlık bir tam sayıdır:

  • İstemci bunu CONNECT içinde gönderir: "Broker, bana N'den fazla onaylanmamış QoS 1/2 PUBLISH paketi gönderme."
  • Broker bunu CONNACK içinde gönderir: "İstemci, bana N'den fazla onaylanmamış QoS 1/2 PUBLISH paketi gönderme."

Özellik yoksa değer varsayılan olarak 65.535'tir; bu da fiilen "sınır yok" anlamına gelir. 0 değerine izin verilmez.

Uçuşta Sayılanlar

Paket türü Pencereden düşer mi? Ne zaman serbest kalır
QoS 0 PUBLISH Hayır Uygulanamaz
QoS 1 PUBLISH Evet PUBACK alındığında
QoS 2 PUBLISH Evet PUBCOMP alındığında (veya hata reason code'lu PUBREC)
Abonelikte gönderilen retained mesaj QoS 1 veya 2 ile teslim edilirse evet Normal onay
Kuyruktaki çevrimdışı mesajlar QoS 1 veya 2'de evet Normal onay

Gönderen taraf bir sayaç tutar (spesifikasyon buna send quota der). Her QoS 1 veya 2 PUBLISH sayacı bir azaltır; tamamlanan her onay bir artırır. Sayaç sıfıra ulaştığında gönderen QoS 1 ve 2 mesajlarını göndermeyi durdurup beklemek zorundadır. QoS 0 mesajlarını göndermeye yine devam edebilir ve spesifikasyon PINGREQ göndermeyi sürdürmesine de izin verir; dolayısıyla keep alive etkilenmez.

Sınır Aşılırsa Ne Olur?

Bir gönderen pencereyi yok sayarsa ve alıcı, bildirdiğinden daha fazla onaylanmamış QoS 1/2 mesajı alırsa, alıcı 0x93 (Receive Maximum exceeded) reason code'uyla bağlantıyı kesmelidir. Pratikte bunu nadiren görürsünüz, çünkü yaygın kütüphaneler pencereyi otomatik olarak uygular. Gördüğünüzde ise neredeyse her zaman özel yazılmış veya çok eski bir istemci uygulamasına işaret eder.

Yavaş Cihazlar için Neden Önemlidir?

10 dakikalık bir Wi-Fi kesintisinden sonra yeniden bağlanan bir ESP32 düşünün. Oturumunda kuyruğa alınmış 200 QoS 1 yapılandırma güncellemesi bulunuyor. Akış kontrolü olmadan broker 200 mesajın hepsini bir anda gönderebilir. Receive maximum değeri 5 olduğunda broker beş mesaj gönderir, PUBACK'leri bekler, ardından her onay geldikçe yenilerini gönderir. Bellek kullanımı sınırlı kalır, işleme hızı yetişir ve cihaz yanıt vermeye devam eder.

Pencere, backend tüketicileri için de doğal bir geri basınç (back-pressure) sağlar: bir worker PUBACK'i yalnızca mesajı veritabanına yazdıktan sonra gönderiyorsa, küçük bir receive maximum, broker'ın worker'ın kaldırabileceğinden fazla iş yığmasını engeller. Bu, birkaç worker'ın tek bir akışı paylaştığı ve her worker'ın penceresinin uçuştaki işlerden aldığı payı sınırladığı MQTT paylaşımlı abonelikleri için faydalı bir tamamlayıcıdır.

İstemcilerde Receive Maximum Ayarlamak

broker.connectmq.com adresindeki herkese açık MQTT test broker'ında connectmq/demo/r2m6/... gibi benzersiz bir önekle test edin. Herkese açık alan herkese açıktır; bu yüzden sahte payload'lar kullanın.

mosquitto_sub

mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv5 \
  -i recvmax-demo-r2m6 -q 1 -v -d \
  -D connect receive-maximum 5 \
  -t 'connectmq/demo/r2m6/#'

-d çıktısı, gönderdiğiniz CONNECT özelliklerini ve broker'ın döndürdüğü CONNACK özelliklerini (broker bir değer ayarladıysa kendi receive maximum değeri dahil) gösterir.

Python (paho-mqtt 2.x)

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

def on_connect(client, userdata, flags, reason_code, properties):
    server_rm = getattr(properties, "ReceiveMaximum", 65535)
    print("Connected:", reason_code, "| broker receive maximum:", server_rm)
    client.subscribe("connectmq/demo/r2m6/#", qos=1)

def on_message(client, userdata, msg):
    # Yavaş bir cihazı simüle et; paho PUBACK'i bu callback döndükten sonra gönderir
    time.sleep(0.5)
    print("Handled", msg.topic, msg.payload.decode())

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id="recvmax-py-r2m6",
                     protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_message = on_message

# *Bizim* eş zamanlı olarak gönderdiklerimizi sınırla (giden pencere)
client.max_inflight_messages_set(10)

# Broker'dan *onun* bize gönderdiklerini sınırlamasını iste (gelen pencere)
props = Properties(PacketTypes.CONNECT)
props.ReceiveMaximum = 5

client.connect("broker.connectmq.com", 1883, keepalive=60, properties=props)
client.loop_forever()

Başka bir terminalden ani bir mesaj yükü publish edin ve mesajların sabit bir hızla gelişini izleyin:

for i in $(seq 1 30); do
  mosquitto_pub -h broker.connectmq.com -p 1883 -i burst-r2m6 \
    -q 1 -t 'connectmq/demo/r2m6/burst' -m "msg $i"
done

Callback içindeki time.sleep çağrısının paho'nun ağ döngüsünü de bloke ettiğini unutmayın. Bu gösterim için sorun değildir, ancak üretimde yavaş işleri ayrı bir thread'e taşıyıp döngüyü serbest tutun; aksi halde keep alive ping'leri gecikir.

Node.js (MQTT.js v5)

const mqtt = require("mqtt");

const client = mqtt.connect("mqtts://broker.connectmq.com:8883", {
  clientId: "recvmax-node-r2m6",
  protocolVersion: 5,
  properties: { receiveMaximum: 5 },
});

client.on("connect", (connack) => {
  console.log("broker properties:", connack.properties);
  client.subscribe("connectmq/demo/r2m6/#", { qos: 1 });
});

client.on("message", (topic, payload) => {
  console.log(topic, payload.toString());
});

Receive Maximum Değerini Seçmek

İstemci Önerilen değer Neden
Mikrodenetleyici (ESP32, ESP8266) 1 ila 10 Sınırlı RAM, sıralı işleme
Raspberry Pi gateway 10 ila 50 Daha fazla bellek, ama hâlâ mütevazı CPU
Veritabanına yazan backend worker'ı Kabaca sürdürebildiği paralel yazma sayısı Geri basınç gerçek aktarım hızıyla eşleşir
Canlı değerleri gösteren dashboard Varsayılan Çoğunlukla sınırlanmayan QoS 0 trafiği

1 değeri katı biçimde tek tek işleme sağlar; bu da sıralama mantığını basitleştirebilir, ancak yüksek gecikmeli bağlantılarda aktarım hızından ödün verir. Uçuştaki her yuva bir gidiş dönüş gerektirir; bu nedenle yüksek gecikmeli bir hücresel bağlantıda çok küçük bir pencere aktarım hızını belirgin şekilde sınırlayabilir. Gerçek trafiğinizle ölçün.

Receive Maximum ve Mesaj Sıralaması

1'den büyük bir pencere MQTT sıralama garantilerini bozmaz: broker bir topic'teki mesajları hâlâ aldığı sırayla gönderir ve istemci de onları o sırayla alır. Değişen şey, aynı anda kaç mesajın onay bekleyebileceğidir. Uygulamanız mesajları sırasız onaylıyorsa, örneğin bir thread havuzuna devrederek, işleme sırası protokolün değil sizin sorumluluğunuzdadır. Pencere tek bir tarafta yapılandırılmak yerine protokolün kendisi tarafından müzakere edildiği için davranış; ConnectMQ broker'ına, yerel bir Mosquitto'ya veya başka herhangi bir MQTT 5 broker'ına bağlansanız da aynıdır.

Sorun Giderme Kontrol Listesi

  1. Yeniden bağlandıktan sonra mesajlar yavaş geliyor. Bu, pencerenin çalıştığını gösterir. Cihaz kaldırabiliyorsa değeri artırın veya message expiry ile birikimi azaltın.
  2. Cihazın belleği hâlâ tükeniyor. Trafiğin çoğunun QoS 0 olup olmadığını kontrol edin; Receive Maximum onu sınırlamaz. Maksimum paket boyutunu da kontrol edin.
  3. Publisher takılıyor. Broker'ın receive maximum değeri küçük olduğu veya PUBACK'ler yavaş geldiği için istemcinizin send quota'sı sıfıra ulaştı. CONNACK özelliklerini loglayın.
  4. 0x93 ile bağlantı kesiliyor. Bir istemci izin verilenden fazla uçuşta mesaj gönderdi; istemci kütüphanesini güncelleyin veya düzeltin.
  5. Ayarın hiçbir etkisi yok. MQTT 3.1.1 ile bağlanıyorsunuz. Receive Maximum yalnızca MQTT 5'te vardır.

Kuyruktaki mesajların en başta nasıl biriktiğine dair daha geniş bir bakış için MQTT'nin çevrimdışı istemciler için mesajları nasıl kuyruğa aldığına göz atın. Protokolde yeni misiniz? MQTT eğitimi ile başlayın.

Akış Kontrolünü ConnectMQ'da Ayarlayın

ConnectMQ, MQTT 3.1.1 ve 5.0'ı TCP, TLS, WebSocket ve güvenli WebSocket üzerinde çalıştırır; böylece Receive Maximum gibi MQTT 5 özellikleri her istemciden çalışır. Plan bazlı kotalar ve taşma koruması paylaşılan bir buluttaki MQTT broker'ını kararlı tutarken Receive Maximum tek tek cihazlarınızı korur. Kredi kartı gerektirmeden ücretsiz bir Serverless broker oluşturun, YOUR_USERNAME, YOUR_PASSWORD ve YOUR_CLIENT_ID ile bağlanın ve cihazlarınıza test amaçlı ani yükler göndermek için portalın tarayıcı içi istemcisini kullanın. Üretim filoları için yönetilen bir MQTT broker broker operasyon işini tamamen ortadan kaldırır.

Sık Sorulan Sorular

Varsayılan MQTT receive maximum değeri nedir?

Özellik gönderilmezse receive maximum 65.535'tir; bu da fiilen pratik bir sınır olmadığı anlamına gelir. Akış kontrolü elde etmek için istemcilerin açıkça daha küçük bir değer ayarlaması gerekir.

Receive maximum QoS 0 mesajlarını sınırlar mı?

Hayır. Yalnızca henüz onaylanmamış QoS 1 ve QoS 2 PUBLISH paketlerini sayar. QoS 0 mesajları bu anlamda hiçbir zaman uçuşta değildir.

Receive maximum MQTT 3.1.1'de mevcut mu?

Hayır. Bu bir MQTT 5 özelliğidir. MQTT 3.1.1 istemcileri, broker'a iletilmeyen kütüphaneye özgü uçuş ayarlarına güvenir.

0x93 reason code'u ne anlama gelir?

Receive Maximum exceeded anlamına gelir: gönderenin uçuşta, alıcının izin verdiğinden fazla onaylanmamış QoS 1 veya 2 mesajı vardı; bu yüzden alıcı bağlantıyı kapattı.

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