Broker testleri

Harici MQTT Uptime İzleme ve Alarm

MQTT broker uptime'ını dışarıdan izleyin: sentetik publish/subscribe probe'u, sertifika süresi, cron, heartbeat, Slack ve PagerDuty alarmları ve SLO hesapları.

Güncellendi · 9 dk okuma

Harici MQTT Uptime İzleme ve Alarm

Harici uptime izleme tek bir soruyu yanıtlar: ağınızın dışındaki bir cihaz şu anda broker'a bağlanıp mesaj alışverişi yapabilir mi? Dahili metrikler bunu yanıtlayamaz. DNS hatalarını, süresi dolmuş sertifikaları, bozuk load balancer'ları veya bir firewall değişikliğini görmezler. Bunları yalnızca bir istemci gibi davranan ve dışarıdan çalışan bir probe görür.

Bu rehber o probe'u oluşturur, zamanlanmış olarak çalıştırır, alarmları Slack'e veya PagerDuty'ye yönlendirir ve kontrol aralığını ve alarm eşiğini seçmek için gereken SLO hesaplarını gösterir.

MQTT broker'ı için "ayakta" ne demek?

"Port açık" zayıf bir tanımdır. Bir broker ancak aşağıdaki tüm katmanlar çalıştığında işe yarar:

KatmanKontrolYakaladığı tipik hata
DNSHostname çözümleniyorSüresi dolmuş alan adı, taşıma sonrası yanlış kayıt
TCP8883 portu bağlantı kabul ediyorFirewall, security group, broker süreci kapalı
TLSHandshake başarılı, sertifika N gün daha geçerliSüresi dolmuş veya eşleşmeyen sertifika
MQTT CONNECTBaşarı kodlu CONNACKKimlik doğrulama backend'i çökmüş, kimlik bilgileri değişmiş, bağlantı limiti dolmuş
Gidiş-dönüşYayınlanan mesaj zaman aşımı içinde alınıyorYönlendirme bozuk, cluster bölünmüş, aşırı yük

Her katmanı ayrı ayrı kontrol edin ve hangisinin başarısız olduğunu raporlayın. "TLS başarısız, sertifika süresi dolmuş" beş dakikada düzeltilir. "Probe başarısız" ise yarım saatlik bir araştırma başlatır. Tek seferlik manuel kontroller için MQTT broker durumunu kontrol etme ve MQTT portunun açık olup olmadığını test etme yazılarına bakın.

Mosquitto istemcileriyle minimal bir probe

mosquitto_pub ve mosquitto_sub zaten kuruluysa bir shell probe'u bir düzine satıra sığar:

mqtt-probe.sh
#!/usr/bin/env bash
set -u
HOST=broker.connectmq.com; PORT=8883
TOPIC="testmqtt/uptime/$(hostname)-$$"
MSG="ping-$(date +%s)"
OUT=$(mktemp)

mosquitto_sub -h "$HOST" -p "$PORT" --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t "$TOPIC" -q 1 -C 1 -W 10 > "$OUT" &
SUB=$!
sleep 1
mosquitto_pub -h "$HOST" -p "$PORT" --capath /etc/ssl/certs \
  -u "$MQTT_USER" -P "$MQTT_PASS" -t "$TOPIC" -q 1 -m "$MSG"
wait $SUB

if grep -qx "$MSG" "$OUT"; then echo "OK"; rm -f "$OUT"; exit 0
else echo "FAIL: no round trip within 10 s"; rm -f "$OUT"; exit 1; fi

-C 1 abonenin bir mesajdan sonra çıkmasını, -W 10 ise on saniye sonra vazgeçmesini sağlar. Bir zamanlayıcının veya heartbeat servisinin ihtiyaç duyduğu tek şey çıkış kodudur.

Python ile katmanlı bir probe

Bu sürüm (paho-mqtt 2.x) her katmanı kontrol edip süresini ölçer, sertifikanın dolmasına kalan gün sayısını raporlar ve loglara göndermesi kolay tek satırlık bir JSON yazdırır:

mqtt_uptime_probe.py
import json, os, socket, ssl, sys, threading, time, uuid
import paho.mqtt.client as mqtt

HOST, PORT, TIMEOUT = "broker.connectmq.com", 8883, 10
result = {"host": HOST, "ts": int(time.time())}

def fail(stage, detail):
    result.update(ok=False, stage=stage, detail=str(detail))
    print(json.dumps(result)); sys.exit(1)

t = time.perf_counter()
try:
    socket.getaddrinfo(HOST, PORT)
except OSError as e:
    fail("dns", e)
try:
    ctx = ssl.create_default_context()
    with socket.create_connection((HOST, PORT), timeout=TIMEOUT) as raw:
        with ctx.wrap_socket(raw, server_hostname=HOST) as tls:
            not_after = ssl.cert_time_to_seconds(tls.getpeercert()["notAfter"])
except ssl.SSLError as e:
    fail("tls", e)
except OSError as e:
    fail("tcp", e)
result["cert_days_left"] = int((not_after - time.time()) // 86400)
result["tls_ms"] = round((time.perf_counter() - t) * 1000)

topic = f"testmqtt/uptime/{uuid.uuid4().hex[:8]}"
connack, got = {}, threading.Event()
c = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"testmqtt-uptime-{uuid.uuid4().hex[:6]}")
c.username_pw_set(os.getenv("MQTT_USER"), os.getenv("MQTT_PASS"))
c.tls_set_context(ctx)
c.on_connect = lambda cl, ud, fl, rc, pr: (connack.update(rc=rc),
                                           None if rc.is_failure else cl.subscribe(topic, qos=1))
c.on_subscribe = lambda cl, ud, mid, rcs, pr: cl.publish(topic, "ping", qos=1)
c.on_message = lambda cl, ud, msg: got.set()

t = time.perf_counter()
try:
    c.connect(HOST, PORT, keepalive=15)
except OSError as e:
    fail("connect", e)
c.loop_start()
ok = got.wait(TIMEOUT)
c.disconnect(); c.loop_stop()
if "rc" not in connack:
    fail("connect", "no CONNACK")
if connack["rc"].is_failure:
    fail("connect", connack["rc"])
if not ok:
    fail("roundtrip", f"no message within {TIMEOUT} s")
result.update(ok=True, roundtrip_ms=round((time.perf_counter() - t) * 1000))
print(json.dumps(result))
sys.exit(2 if result["cert_days_left"] < 14 else 0)

0 çıkış kodu sağlıklı, 1 kapalı (stage alanı nerede olduğunu söyler), 2 ise ayakta ama sertifikanın süresi iki haftadan kısa sürede doluyor demektir. Sonuncusu bir uyarıdır, nöbetçiyi uyandıracak bir alarm değil. connect aşaması başarısız olduğunda reason code (örneğin Not authorized) sorunun kimlik bilgilerinde mi yoksa ACL'de mi olduğunu söyler. Kodu reason code aracında veya MQTT bağlantı hataları yazısında arayın.

Probe'u zamanlamak

  • Broker'ın ağı dışındaki küçük bir VM'de cron veya systemd timer: * * * * * /opt/probe/mqtt_uptime_probe.py >> /var/log/mqtt-probe.log 2>&1. Basittir ve dakikada bir çalışır.
  • Birden fazla konum. Aynı probe'u iki veya üç bölgeden ya da sağlayıcıdan çalıştırın. Çoğunluk başarısız olduğunda alarm verin. Tek bir konumun başarısız olması genellikle o konumun ağından kaynaklanır.
  • GitHub Actions schedule kritik olmayan kontroller için işe yarar ama minimum aralık beş dakikadır ve çalıştırmalar gecikmeli başlayabilir. Nöbetçiyi uyarmak için uygun değildir.
  • Uptime Kuma (self-hosted) bir MQTT monitör türü içerir ve arayüz tercih ediyorsanız iyi çalışır.

Probe'u çalıştıran sistem de çökebilir. Bir heartbeat (dead man's switch) kullanın: her başarılı çalıştırmadan sonra probe, Healthchecks.io veya bir Uptime Kuma push monitörü gibi bir heartbeat servisindeki URL'ye ping atar. Ping'ler durursa ya broker ya da probe sunucusu çökmüştür ve her iki durumda da alarm alırsınız:

Heartbeat'li cron satırı
* * * * * /opt/probe/mqtt-probe.sh && curl -fsS -m 10 --retry 3 "$HEARTBEAT_URL" > /dev/null

Alarm kanalları

Alarmları gerçekten birinin göreceği yere ve ancak yeterli kanıt olduğunda gönderin. Yaygın bir kural en az iki konumdan art arda üç başarısızlık ve sorun düzeldiğinde bir kurtarma mesajıdır.

Slack incoming webhook
curl -fsS -X POST -H 'Content-Type: application/json' \
  -d '{"text":":red_circle: MQTT probe failed at stage tls (broker.connectmq.com:8883)"}' \
  "$SLACK_WEBHOOK_URL"
PagerDuty Events API v2
curl -fsS -X POST https://events.pagerduty.com/v2/enqueue \
  -H 'Content-Type: application/json' \
  -d '{"routing_key":"'"$PD_ROUTING_KEY"'","event_action":"trigger",
       "dedup_key":"mqtt-probe-broker",
       "payload":{"summary":"MQTT round trip failing","source":"mqtt-probe","severity":"critical"}}'

Olayı otomatik olarak kapatmak için aynı isteği "event_action":"resolve" ve aynı dedup_key ile gönderin. Sertifika süresi uyarılarını Slack'te veya e-postada tutun. Bunlar bu hafta ilgilenilmesi gereken işlerdir, gece 3'te değil. Zaten Prometheus kullanıyorsanız probe'u metrik olarak dışa aktarın ve alarmları orada kurun. Ayrıntılar için Prometheus ve Grafana ile MQTT izleme yazısına bakın.

SLO hesapları

Bir erişilebilirlik hedefi ancak kesinti bütçesiyle birlikte anlam kazanır:

Erişilebilirlik30 günde kesintiYılda kesinti
%997 sa 12 dk3,65 gün
%99,53 sa 36 dk1,83 gün
%99,943,2 dk8 sa 46 dk
%99,9521,6 dk4 sa 23 dk
%99,994,3 dk52,6 dk

Bunu başarılı probe sayısı ÷ toplam probe sayısı olarak ölçün. Dakikada bir probe 30 günde 43.200 örnek üretir; yani %99,9, 43 başarısız probe'a izin verir. Bundan üç sonuç çıkar:

  • Aralık doğruluğu sınırlar. Dakikada bir probe ile 20 saniyelik bir kesinti gözden kaçabilir ya da tam bir dakika sayılabilir. %99,99'u ölçmek istiyorsanız her 10–15 saniyede bir kontrol edin.
  • Tespit süresi bütçeyi yer. Dakikalık aralıklarla üç başarısızlık, birinin uyarılmasına kadar yaklaşık üç dakika demektir. %99,9 için (43 dakika) bu sorun değildir ama %99,99'da neredeyse bütçenin tamamıdır.
  • Sizin SLO'nuz sağlayıcının SLA'sı değildir. SLA broker'ı kapsar. Probe'unuz ise DNS'iniz, sertifikalarınız ve ağınız dahil tüm yolu ölçer. İkisini karşılaştırmadan önce MQTT broker SLA ve uptime yazısını okuyun.

Hata bütçesini takip edin: ayın ortasında 43 dakikanızın 30'u harcanmışsa bütçe toparlanana kadar broker'da riskli değişiklikleri dondurun.

Alarm yolunu test edin

Hiç başarısız olmamış bir probe test edilmemiş demektir. Ona güvenmeden önce:

  1. Yanlış bir parola girin ve connect aşamasının başarısız olduğunu, alarmın Slack'e veya PagerDuty'ye ulaştığını doğrulayın.
  2. HOST değerini çözümlenmeyen bir ada yönlendirin ve stage: dns çıktısını doğrulayın.
  3. Cron işini durdurun ve heartbeat servisinin sizi uyardığını doğrulayın.
  4. Probe'un gördüğünün gerçekle örtüştüğünü elle kontrol edin: probe çalışırken online MQTT istemcisiyle bağlanın ve probe topic'ine publish edin.

Harici uptime izleme küçük bir betik, bir zamanlayıcı ve bir heartbeat'ten ibarettir. Her katmanı ayrı kontrol edin, yalnızca birden fazla konumdan gelen tekrarlı başarısızlıklarda alarm verin, probe aralığını SLO'nuza göre seçin ve alarmların ulaştığını kanıtlamak için kurulumu bir kez bilerek bozun.

Sıkça sorulan sorular

MQTT uptime'ını izlemek için 1883 portunun açık olduğunu kontrol etmek yeterli mi?

Hayır. Bir broker TCP bağlantılarını kabul ederken girişleri reddedebilir, TLS'te başarısız olabilir veya mesajları yönlendirmeyebilir. Gerçek bir uptime kontrolü kimlik bilgileriyle bağlanır, abone olur, bir mesaj yayınlar ve mesajın belirli bir süre içinde geldiğini doğrular.

Bir MQTT uptime probe'u ne sıklıkla çalışmalı?

Dakikada bir iyi bir varsayılandır. Aralık, erişilebilirliği ne kadar doğru ölçebileceğinizi sınırlar: dakikada bir kontrolle bir dakikadan kısa kesintiler gözden kaçabilir ve yaklaşık dört dakikalık aylık %99,99 bütçesi, üç hatalık bir alarm tetiklenmeden tükenir.

%99,9 ne kadar kesintiye izin verir?

30 günlük bir ayda yaklaşık 43 dakika, yılda ise yaklaşık 8 saat 46 dakika. %99,95 ayda yaklaşık 22 dakikaya, %99,99 ise yaklaşık 4,3 dakikaya izin verir.