fix: bridge Kafka write async (v0.1.69) — MQTT callback не блокируется

This commit is contained in:
Naeel
2026-04-06 18:26:03 +03:00
parent c0a08ae78d
commit 387932ce10
5 changed files with 125 additions and 15 deletions
+15 -13
View File
@@ -1,5 +1,5 @@
// Создано: 2026-04-04
// Изменено: 2026-04-06 (заменён RabbitMQ на Kafka)
// Изменено: 2026-04-06 (fix: Kafka write async — MQTT callback не блокируется)
// mqtt-bridge/main.go — сервис-мост: MQTT (EMQX) → Kafka.
//
// Роль в архитектуре:
@@ -80,14 +80,18 @@ func main() {
"kafka_brokers", cfg.KafkaBrokers,
)
// Kafka writer — асинхронный, с автоматическим созданием топика.
// Kafka writer — полностью асинхронный: WriteMessages возвращается немедленно,
// не блокируя MQTT callback. Kafka batching работает в фоне.
// Ошибки доставки логируются через ErrorLogger — не блокируют MQTT loop.
kafkaWriter := &kafka.Writer{
Addr: kafka.TCP(strings.Split(cfg.KafkaBrokers, ",")...),
Topic: iotTelemetryTopic,
Balancer: &kafka.LeastBytes{},
// Позволяет продолжать работу при временной недоступности Kafka (буфер в памяти)
Async: false,
Addr: kafka.TCP(strings.Split(cfg.KafkaBrokers, ",")...),
Topic: iotTelemetryTopic,
Balancer: &kafka.LeastBytes{},
Async: true, // MQTT callback не блокируется на ACK от Kafka
RequiredAcks: kafka.RequireOne,
ErrorLogger: kafka.LoggerFunc(func(msg string, args ...interface{}) {
log.Error("kafka async write error", "detail", fmt.Sprintf(msg, args...))
}),
}
defer kafkaWriter.Close()
@@ -216,15 +220,13 @@ func buildMQTTMessageHandler(ctx context.Context, w *kafka.Writer, log *slog.Log
}
// Ключ = namespace — Kafka будет группировать сообщения одного тенанта
// на одну партицию (для упорядоченной обработки на consumer side)
err = w.WriteMessages(ctx, kafka.Message{
// на одну партицию (для упорядоченной обработки на consumer side).
// WriteMessages с Async=true возвращается немедленно — не блокирует MQTT callback.
// Ошибки доставки идут в ErrorLogger выше.
_ = w.WriteMessages(ctx, kafka.Message{
Key: []byte(ns),
Value: body,
})
if err != nil {
log.Error("publish to Kafka", "topic", iotTelemetryTopic, "namespace", ns, "err", err)
return
}
log.Info("forwarded IoT telemetry to Kafka",
"mqtt_topic", topic,