MQTT 3.1.1 vs 5.0, bir proje prototip aşamasını geçtiğinde her ekibin karşılaştığı sürüm sorusudur: Yeni protokol geçişe değer mi ve eski ile yeni cihazlar bir arada yaşayabilir mi? Bu rehber iki sürümün hatta ve pratikte nasıl davrandığını karşılaştırıyor, popüler istemci kütüphanelerinden hangilerinin MQTT 5'i desteklediğini listeliyor ve karma bir filoyu her seferinde bir istemci grubu olacak şekilde yükseltmeniz için bir geçiş kontrol listesi sunuyor.
Kısa Bir Tarihçe
MQTT 3.1.1 2014'te bir OASIS standardı oldu ve hâlâ en yaygın kullanılan sürümdür. Küçüktür, kararlıdır ve neredeyse her istemci kütüphanesi ve cihaz tarafından desteklenir. MQTT 5.0 ise 2019'da OASIS standardı olarak onu izledi. Aynı temel modeli, yani topic'leri, QoS seviyelerini, retained message'ları ve Last Will'i korudu ve büyük kurulumların elle inşa ettiği özellikleri ekledi: daha anlaşılır hatalar, süre dolumu, akış kontrolü, metadata ve yük dengeleme. 4. sürüm yoktur; 3.1.1 için protocol level baytı 4, 5.0 için 5'tir. Kütüphanelerin 3.1.1'i çoğu zaman "protocol version 4" olarak adlandırmasının nedeni budur.
Geçiş açısından iyi haber, bir broker'ın her iki sürüme aynı anda hizmet verebilmesidir. Her istemci sürümünü CONNECT paketinde bildirir ve mesajlar aynı topic'ler üzerinde 3.1.1 ve 5.0 istemcileri arasında akar.
MQTT 3.1.1 vs 5.0 Yan Yana
| Davranış | MQTT 3.1.1 | MQTT 5.0 |
|---|---|---|
| Hata raporlama | 0-5 arası CONNACK dönüş kodları; diğer hataların çoğunda bağlantı yalnızca kapatılır | CONNACK, PUBACK, SUBACK, UNSUBACK, DISCONNECT ve diğerlerinde reason code'lar ve isteğe bağlı reason string'ler |
| Oturum ömrü | Clean session bayrağı: ya sonsuza kadar ya hiç | Clean start ve saniye cinsinden session expiry interval |
| Mesaj ömrü | Mesajlar oturumlarda süresiz bekler | Mesaj başına message expiry interval |
| Yük dengeli tüketiciler | Standart değil | $share/group/filter ile shared subscription'lar |
| Topic ek yükü | Her PUBLISH'te tam topic | Topic alias, topic'i bir tam sayıyla değiştirir |
| Metadata | Yalnızca payload içinde | User property'ler, content type, payload format indicator |
| İstek/yanıt | Yalnızca konvansiyon | Response topic ve correlation data |
| Akış kontrolü | Standart yok | Receive maximum, maximum packet size |
| Sunucu tarafından bağlantı kesme | Sunucu soketi sessizce kapatır | Sunucu reason code içeren bir DISCONNECT gönderir |
| Subscription seçenekleri | Yalnızca QoS | No local, retain as published, retain handling, subscription identifier'lar |
| Will mesajı | Beklenmedik kopmada hemen gönderilir | İsteğe bağlı will delay interval |
| Kimlik doğrulama | Kullanıcı adı ve parola | Ayrıca AUTH paketiyle gelişmiş kimlik doğrulama |
| Sunucu yetenekleri | Örtük | Sunucu maximum QoS, retain kullanılabilirliği, keep alive geçersiz kılma ve atanmış client ID bildirebilir |
Pratikte En Önemli Değişiklikler
Reason code'lar. 3.1.1'de bir broker bir kota veya yetki nedeniyle bir publish'i reddederse, istemci çoğu zaman yalnızca bağlantının koptuğunu görür ve tahmin yürütmek zorunda kalır. MQTT 5'te broker nedenini söyleyebilir; örneğin 0x97 (kota aşıldı) veya 0x87 (yetkisiz). Yalnızca bu bile hata ayıklamayı ciddi şekilde kısaltır. MQTT reason code'ları referansı hepsini listeliyor.
Oturum ve mesaj süresi dolumu. 3.1.1'de kalıcı bir oturum istemci geri dönene kadar yaşar; bu da broker'ın aylar önce hizmetten çıkarılmış cihazlar için mesaj tutması anlamına gelebilir. MQTT 5, istemcinin "oturumumu 10 dakika tut" demesine, publisher'ların ise "bu komut 30 saniye sonra işe yaramaz" demesine olanak tanır. Ayar önerileri için MQTT session expiry interval yazısına bakın.
Shared subscription'lar. Bir backend servisinin birden fazla örneği $share/workers/orders/+/new filtresine subscribe olabilir ve broker mesajları aralarında dağıtır. MQTT 5'ten önce bu, broker'a özgü uzantılar ya da ayrı bir kuyruk gerektiriyordu.
User property'ler ve istek/yanıt. Şema sürümü veya trace ID gibi metadata her payload'ın içine gömülmek yerine property'lerde taşınabilir; istek/yanıt akışları ise standart bir response topic ve correlation data'ya kavuşur.
Örneklerle özellik özellik bir tur için MQTT 5 özellikleri yazısını okuyun.
Neler Değişmiyor?
Topic sözdizimi ve wildcard'lar, üç QoS seviyesi, retained message'lar, Last Will, keep alive, portlar ve TLS aynı şekilde çalışır. Payload'lar hâlâ opak baytlardır. Bir 3.1.1 subscriber'ı, bir 5.0 istemcisinin publish ettiği mesajları alır; yalnızca MQTT 5 property'lerini görmez. Kademeli bir yükseltmeyi mümkün kılan da bu uyumluluktur.
İstemci Kütüphanesi Desteği
| Platform | Kütüphane | MQTT 5 desteği |
|---|---|---|
| Python | paho-mqtt 2.x | Evet, protocol=mqtt.MQTTv5 geçin |
| Node.js ve tarayıcılar | MQTT.js v5 | Evet, protocolVersion: 5 ayarlayın (varsayılan 4) |
| Go | Eclipse Paho paho.mqtt.golang |
Hayır, yalnızca 3.1.1 |
| Go | Eclipse Paho paho.golang |
Evet, yalnızca MQTT 5 |
| Java | Eclipse Paho Java (mqttv5 paketi), HiveMQ MQTT Client |
Evet |
| .NET | MQTTnet | Evet |
| ESP32 (ESP-IDF) | esp-mqtt | Evet, derleme yapılandırmasında MQTT 5 desteği etkinleştirildiğinde |
| Arduino | PubSubClient, AsyncMqttClient | Hayır, yalnızca 3.1.1 |
| CLI | mosquitto_pub ve mosquitto_sub | Evet, -V mqttv5 ile |
Kütüphane sürümleri değişir; bu yüzden karar vermeden önce resmi belgelerle doğrulayın. Dikkat edilmesi gereken desen şu: sunucu tarafı ve gateway kütüphaneleri genellikle MQTT 5'i desteklerken, popüler mikrodenetleyici kütüphanelerinin birçoğu hâlâ yalnızca 3.1.1 destekliyor. Filoların karma hale gelmesinin temel nedeni budur.
Kodda MQTT 5 Özelliklerini Kullanmak
Bu Python örneği MQTT 5 ile bağlanır, 10 dakikalık bir oturum ister, 30 saniyelik süre dolumu ve user property'lerle bir komut publish eder ve reason code'ları yazdırır. Her iki sürümü ve 30 dakikaya kadar session expiry'yi destekleyen herkese açık MQTT test broker'ında çalışır.
import time
import uuid
import paho.mqtt.client as mqtt
from paho.mqtt.packettypes import PacketTypes
from paho.mqtt.properties import Properties
PREFIX = f"connectmq/demo/{uuid.uuid4().hex[:8]}"
def on_connect(client, userdata, flags, reason_code, properties):
print("CONNACK:", reason_code, "| session present:", flags.session_present)
client.subscribe(f"{PREFIX}/cmd/#", qos=1)
def on_subscribe(client, userdata, mid, reason_code_list, properties):
print("SUBACK:", [str(rc) for rc in reason_code_list])
def on_message(client, userdata, msg):
props = msg.properties
user_props = getattr(props, "UserProperty", None)
expiry = getattr(props, "MessageExpiryInterval", None)
print(f"{msg.topic} {msg.payload.decode()} user={user_props} expiry={expiry}")
def on_publish(client, userdata, mid, reason_code, properties):
print("PUBACK:", reason_code)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"v5-demo-{uuid.uuid4().hex[:8]}",
protocol=mqtt.MQTTv5)
client.on_connect = on_connect
client.on_subscribe = on_subscribe
client.on_message = on_message
client.on_publish = on_publish
connect_props = Properties(PacketTypes.CONNECT)
connect_props.SessionExpiryInterval = 600 # oturumu 10 dakika tut
client.connect("broker.connectmq.com", 1883, keepalive=30,
clean_start=False, properties=connect_props)
client.loop_start()
time.sleep(1)
pub_props = Properties(PacketTypes.PUBLISH)
pub_props.MessageExpiryInterval = 30
pub_props.UserProperty = [("schema", "v2"), ("source", "ops-console")]
pub_props.ContentType = "application/json"
client.publish(f"{PREFIX}/cmd/pump7", '{"action":"stop"}', qos=1,
properties=pub_props)
time.sleep(2)
client.loop_stop()
client.disconnect()
Birlikte çalışabilirliği görmek için başka bir terminalde aynı topic'e bir 3.1.1 subscriber'ı çalıştırın. Payload'ı alır ama property'leri almaz.
mosquitto_sub -h broker.connectmq.com -p 1883 -V mqttv311 \
-i v311-check-$RANDOM -t "connectmq/demo/+/cmd/#" -v
Geçiş Kontrol Listesi
3.1.1'den 5.0'a tek seferde büyük bir geçiş yapmadan ilerlemek için bu listeyi kullanın.
- Broker desteğini doğrulayın. Broker'ınız her iki sürümü aynı anda kabul etmelidir. ConnectMQ bunu yapar; böylece eski ve yeni istemciler geçiş sırasında topic'leri paylaşabilir.
- İstemcilerin kütüphane envanterini çıkarın. Her cihaz tipini, gateway'i ve servisi MQTT kütüphanesi ve sürümüyle listeleyin. Hangilerinin bugün MQTT 5'e geçebileceğini işaretleyin.
- Önce backend servislerini yükseltin. En çok kazanç onlarda olur (reason code'lar, shared subscription'lar, akış kontrolü) ve yeniden dağıtılmaları en kolay olanlar da onlardır.
- Clean session mantığını değiştirin.
clean_session=Truedeğerini session expiry 0 ile clean start'a,clean_session=Falsedeğerini ise "sonsuza kadar" yerine açık bir süre belirlenmiş clean start false'a eşleyin. - Reason code'ları işleyin. CONNACK, SUBACK, PUBACK ve DISCONNECT'teki reason code'ları ve reason string'leri loglayın ve "yetkisiz" gibi yeniden denenemeyecek kodlarda tekrar denemeyi bırakın.
- Kritik veriler için henüz property'lere güvenmeyin. 3.1.1 subscriber'ları var olduğu sürece onların ihtiyaç duyduğu her şey payload'da veya topic'te kalmalıdır.
- Süre dolumunu bilinçli şekilde devreye alın. Message expiry'yi önce, eskimiş teslimatın zararlı olduğu komutlara ve zamana duyarlı alarmlara ekleyin.
- Shared subscription'ları benimseyin; yatay ölçeklenen tüketiciler için kullanın ve örnekler arasında kendi yazdığınız tekrar ayıklama mantığını kaldırın.
- Gateway'leri ve cihazları en son yükseltin; gruplar halinde, her dalgadan sonra bağlantı durumunu ve hata oranlarını izleyerek.
- Temelleri yeniden test edin. Yeniden bağlanma, Last Will, retained durum ve kalıcı oturumlar eskisi gibi davranmalıdır; MQTT test kontrol listesi her birini ele alıyor.
Yükseltmeli misiniz?
Yeni projelerde kütüphanelerinizin desteklediği her yerde MQTT 5 ile başlayın. Mevcut filolarda servisleri ve gateway'leri şimdi, cihazları ise fırsat buldukça, örneğin bir sonraki firmware döngüsünde yükseltin. Kütüphanesi yalnızca 3.1.1 destekleyen kısıtlı cihazlar için acele etmenin pek bir nedeni yoktur; çünkü her iki sürümü konuşan bir broker bu baskıyı ortadan kaldırır. Ekibe yeni katılanlar varsa MQTT eğitimi ortak temelleri ele alıyor.
Her iki sürümü destekleyen yönetilen bir MQTT broker, geçişi sorunsuz hale getirir. ConnectMQ, MQTT 3.1.1 ve 5.0 istemcilerini aynı broker'da kabul eder ve session expiry, message expiry, topic alias, response topic, retained message'lar ve reason code'lar dahil MQTT 5 özelliklerini destekler; shared subscription'lar ise ücretli Serverless planda kullanılabilir.
ConnectMQ'da Kendi Hızınızda Yükseltin
app.connectmq.com adresinde kredi kartı gerekmeden ücretsiz bir Serverless broker oluşturun, bir 3.1.1 cihazı ve bir MQTT 5 servisini bağlayın ve geçişin geri kalanını planlamadan önce ikisinin birlikte çalıştığını doğrulayın.
Sık Sorulan Sorular
MQTT 3.1.1 ve MQTT 5.0 uyumlu mu?
Aynı broker üzerinde evet. İstemciler sürümlerini bağlantı anında seçer ve mesajlar sürümler arasında akar. Bir 3.1.1 subscriber'ı yalnızca MQTT 5 property'lerini almaz.
MQTT 5'in en büyük faydası nedir?
Çoğu ekip için reason code'lardır, çünkü hatalar artık sessiz bağlantı kopmaları olmaktan çıkar. Oturum ve mesaj süresi dolumu ile shared subscription'lar hemen arkasından gelir.
MQTT 3.1.1'e neden protocol version 4 deniyor?
CONNECT paketi bir protocol level baytı taşır; bu değer MQTT 3.1.1 için 4, MQTT 5.0 için 5'tir. MQTT.js gibi kütüphaneler seçeneklerinde bu sayıyı kullanır.
ESP32 cihazlarımı MQTT 5'e yükseltmem gerekiyor mu?
Şart değil. PubSubClient gibi bir 3.1.1 kütüphanesi kullanıyorsanız, backend'iniz MQTT 5'i benimserken cihazlarınız her iki sürümü destekleyen bir broker'a karşı çalışmaya devam edebilir.



