EMQX MQTT Broker Konfigürasyonu
EMQX 5.8.3, Zeus 2.0'ın MQTT broker'ıdır.
Portlar
| Port | Protokol | Erişim |
|---|---|---|
| 1883 | MQTT TCP (plaintext) | localhost only |
| 8883 | MQTT TLS | 0.0.0.0 (ESP32 cihazlar) |
| 18083 | Dashboard HTTP | localhost only |
Authentication
Bootstrap dosyası ile kullanıcı tanımları:
| Kullanıcı | Rol | Açıklama |
|---|---|---|
backend | Service | Backend API MQTT client |
gateway | Device | ESP32 gateway cihazlar |
admin | Superuser | Tam erişim (debug/monitoring) |
zigbee_rpi_gateway_001 | Device | Zigbee2MQTT bridge |
ACL Kuralları
Gateway İzinleri
Publish: Bootstrap topic'leri, telemetri verileri, reported status/config/alarms, OTA progress, ownership ACK
Subscribe: Bootstrap server yanıtları, desired config/templates/devices, komutlar, OTA command/rollback, firmware announcements, ownership commands
Backend İzinleri
Publish: Bootstrap yanıtları, desired config/templates/devices, komutlar, OTA, ownership commands, firmware announcements
Subscribe: Bootstrap hello/claim_ready, tüm telemetri verileri, reported status/config, eventler, OTA progress/status, ownership ACK
Varsayılan Kural
{deny, all} # Tanımlanmamış tüm erişimler reddedilir
TLS Yapılandırması
TLS versiyonları: TLSv1.2, TLSv1.3
Sertifika: /opt/emqx/etc/certs/cert.pem
Anahtar: /opt/emqx/etc/certs/key.pem
CA: /opt/emqx/etc/certs/ca.pem
Production: Let's Encrypt sertifikaları (scripts/setup-ssl.sh)
Development: Self-signed sertifikalar (scripts/generate-emqx-certs.sh)
QoS Politikası
Farklı veri tipleri için kullanılan QoS seviyeleri ve gerekçeleri:
| Veri Tipi | QoS | Gerekçe |
|---|---|---|
| Gerçek zamanlı ölçümler (realtime) | 0 | Sık gönderim (5s aralık), tek bir veri kaybı tolere edilir |
| Enerji sayaçları (energy_kwh) | 1 | Faturalama verisi, kayıp kabul edilemez |
| Konfigürasyon komutları (desired/*) | 1 | Cihaz kurulumu, güvenilir iletim gerekli |
| Bootstrap mesajları | 0 | İlk handshake, başarısız olursa tekrar denenebilir |
| OTA komutları | 1 | Firmware güncelleme komutu, kritik iletim |
| Durum raporları (reported/*) | 0 | Düzenli aralıkla tekrar gönderilir, kayıp tolere edilir |
Not: QoS 2 (exactly once) kullanılmaz. ESP32 cihazların sınırlı kaynakları ve ağ koşulları nedeniyle QoS 2'nin ek yükü kabul edilemez. QoS 1 ile idempotent mesaj tasarımı tercih edilir.
Session Yönetimi
Clean Session
- ESP32 gateway'ler clean session = true kullanır
- Her bağlantıda subscription'lar yeniden kurulur
- Broker tarafında offline mesaj birikimi oluşmaz (kaynak tasarrufu)
Keep-Alive
| Parametre | Değer | Açıklama |
|---|---|---|
| Keep-alive interval | 60 saniye | Client'ın PINGREQ gönderme aralığı |
| Keep-alive multiplier | 1.5x (EMQX default) | 90 saniye içinde sinyal gelmezse bağlantı kopmuş sayılır |
Session Expiry
| Parametre | Değer | Açıklama |
|---|---|---|
| Session expiry interval | 300 saniye | Clean session=false durumunda oturum saklama süresi |
| Maksimum inflight | 32 mesaj | Aynı anda onay bekleyen QoS 1 mesaj sayısı |
| Mesaj kuyruğu limiti | 1000 mesaj | Offline client için saklanacak maksimum mesaj |
Bağlantı Kopma Tespiti
EMQX, gateway bağlantı durumunu webhook ile backend'e bildirir:
POST /api/internal/gateway/connected → Gateway bağlandı
POST /api/internal/gateway/disconnected → Gateway koptu
Backend bu bilgiyi kullanarak cihaz çevrimiçi/çevrimdışı durumunu günceller ve gerektiğinde alarm tetikler.
Retained Message Politikası
| Topic Kategorisi | Retain | Açıklama |
|---|---|---|
zeus/{tenant}/gw/{gw_id}/desired/* | true | Cihaz reconnect olduğunda son konfigürasyonu alır |
zeus/{tenant}/gw/{gw_id}/reported/* | false | Düzenli aralıkla güncellenir, geçmiş değer gereksiz |
zeus/{tenant}/gw/{gw_id}/telemetry/* | false | Sürekli akan veri, retain gereksiz yük oluşturur |
zeus/{tenant}/gw/{gw_id}/ota/* | false | Tek seferlik komutlar, retain riskli (tekrar tetikleme) |
zeus/firmware/announcements | true | Yeni bağlanan gateway'ler güncel firmware bilgisini alsın |
Neden Sadece desired/* ve announcements Retain?
- desired/* topic'leri cihaz konfigürasyonunu taşır. Gateway yeniden başladığında (OTA, güç kesintisi) son geçerli konfigürasyonu hemen alması gerekir
- firmware/announcements topic'i mevcut firmware sürümünü duyurur. Yeni bağlanan gateway güncel sürümü bilmeli
- Telemetri ve reported verileri sürekli yenilendiği için retain gereksiz disk ve bellek yükü oluşturur
- OTA komutlarında retain tehlikelidir: gateway yeniden bağlandığında eski bir OTA komutu tekrar tetiklenebilir
Retain Persistence — Disc Storage
Sorun
Default EMQX konfigürasyonunda retain mesajları sadece bellekte tutulur. Broker restart olduğunda (OTA, host reboot, container redeploy) tüm retain mesajları silinir. Bu durumda:
- Gateway'ler reconnect ederken son
desiredkonfigürasyonu alamaz - Yeni cihaz konfigürasyonu broker'a yeniden push edilene kadar gateway'ler stale veriyle çalışır
- Manuel
rawconfig.push_all_gatewaystask'ı tetiklenmesi gerekir (kullanıcı görünür gecikme)
Çözüm
EMQX retainer backend'i disc storage'a alınır:
# emqx-config/etc/plugins/emqx_retainer.conf veya env
EMQX_RETAINER__BACKEND__STORAGE_TYPE=disc
EMQX_RETAINER__MSG_EXPIRY_INTERVAL=0 # Asla expire etme
EMQX_RETAINER__MSG_CLEAR_INTERVAL=0 # Otomatik temizleme kapalı
| Parametre | Değer | Anlam |
|---|---|---|
STORAGE_TYPE=disc | mnesia disc copies | Mesaj data/mnesia/ altında diske yazılır |
MSG_EXPIRY_INTERVAL=0 | 0 = no expiry | Retain mesajları süresiz kalır |
MSG_CLEAR_INTERVAL=0 | 0 = disabled | Periyodik temizleme yapılmaz |
docker-compose.yml Volume Mount
emqx:
image: emqx/emqx:5.8.3
volumes:
- ./emqx-config/data:/opt/emqx/data # mnesia + retain disk'i
- ./emqx-config/etc:/opt/emqx/etc
- ./emqx-config/log:/opt/emqx/log
./emqx-config/data host volume'u sayesinde container yeniden oluşturulsa bile retain mesajları korunur.
Surgical Deploy Stop Pattern (Issue #247)
Sorun
Deploy sırasında docker compose stop emqx komutu broker'ı anında durdurur. Mnesia transaction'ları yarıda kalabilir, retain mesajları diske flush edilmeden kapanır. Worst case: retain disc dosyası corrupt → broker restart sonrası boş retain.
Çözüm
Graceful shutdown EMQX'in kendi mekanizmasıyla yapılır:
# ❌ Yanlış (sert kapatma)
docker compose stop emqx
# ✅ Doğru (graceful)
docker exec emqx emqx_ctl cluster_call init stop
sleep 5 # mnesia flush için
docker compose stop emqx
Adımlar:
emqx_ctl cluster_call init stop— Tüm internal subsystem'lere graceful stop sinyali- 5 saniye bekleme — mnesia transaction commit ve disc flush
docker compose stop emqx— Container artık temiz state ile kapanır
Bu pattern deploy script'inde EMQX restart gerektiren durumlar için kullanılır (config değişikliği, image upgrade). Retain persistence garantisi sağlar.