· kaynak dev.to (home feed)
Spring Boot Kafka ayarları consumer lag'i sıfırladı, işleme gecikmesini %35 düşürdü
dev.to üzerinde yayımlanan bir üretim deneyimi yazısı, bir fintech servisinin Kafka consumer lag'ini nasıl temizlediğini ve listener eşzamanlılığını partition sayısıyla eşleştirip manuel ack ve DLQ ekleyerek işleme gecikmesini %35 nasıl azalttığını anlatıyor.

Ne yaşandı
dev.to üzerinde yayımlanan bir üretim deneyimi yazısı, bir fintech ekibinin trafik yoğunlukları sırasında Kafka consumer lag'i biriken yüksek hacimli, olay güdümlü bir servisi nasıl rahatlattığını adım adım anlatıyor. Yazarın aktardığına göre, servisin varsayılan Spring Kafka yapılandırması bir payments topic'indeki mesaj hacmine yetişemiyordu. Listener eşzamanlılığı, acknowledgment yönetimi ve hata yönlendirmesi yeniden çalışıldıktan sonra ekip, birikimin temizlendiğini ve API işleme gecikmesinin %35 düştüğünü bildiriyor.
Darboğaz: listener başına tek thread
Yazıdaki ilk sorunun kaynağı Spring'in varsayılan listener davranışı: bir @KafkaListener metodu, aksi yapılandırılmadıkça 1 eşzamanlılıkla çalışıyor. Tek thread kayıtları çektiğinde, hacimdeki her artış işin tüketilme hızından daha hızlı gelmesine neden oluyor ve bu da sürekli büyüyen consumer lag olarak kendini gösteriyor.
Bu durum Kafka'nın paralellik modeline de uygun: bir consumer group içinde bir partition aynı anda yalnızca bir consumer tarafından tüketilebildiğinden, tek thread'li listener, topic'in kaç partition'u olursa olsun tüm hattı tek worker'ın iş hacmiyle sınırlıyor.
Partition sayısıyla uyumlu eşzamanlılık
Anlatılan çözüm, ConcurrentKafkaListenerContainerFactory üzerindeki eşzamanlılığı, topic'in partition sayısıyla eşleşecek şekilde bilinçli olarak seçilmiş 6 değerine yükseltmek. Factory böylece her eşzamanlılık birimi için bir consumer thread oluşturuyor ve grup partition'ları tek yerine altı worker'a dağıtabiliyor.
java factory.setConcurrency(6); factory.getContainerProperties() .setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);
Yazıya göre bu değişiklik, otomatik offset commit'lerinden uzaklaşmayla birlikte uygulanıyor. MANUAL_IMMEDIATE modunda offset'ler, framework'ün zamanlayıcısına değil, bir kayıt gerçekten işlendikten sonra uygulama kodu tarafından commit ediliyor.
Dead-letter queue ile hata yönetimi
İlenemeyen kayıtlar için yazar, handler'ı bir try/catch içine alıyor. Başarılı kayıtlar hemen acknowledge ediliyor. İşleme hata fırlattığında kaydın anahtarı loglanıyor, mesaj bir dead-letter queue'ye yönlendiriliyor ve offset yine de acknowledge ediliyor; böylece zararlı bir mesaj sonsuza kadar yeniden oynatılarak partition'ı kilitleyemiyor.
Dikkat çekmeye değer bir ayrıntı: yazı bu bölümü idempotency ile açık batch işleme olarak sunuyor, ancak gösterdiği kod her çağrımda tek bir ConsumerRecord tüketiyor, kayıt başına acknowledgment yapıyor ve snippet'te hiçbir idempotency mantığı görünmüyor. Aslında gösterilen mekanizma, kayıt başına manuel ack ve açık hata yönlendirmesi; gerçek batch tüketimi isteyen okurların liste tabanlı bir listener imzası kullanması gerekir.
Yazarın çıkarımları
Yazı, consumer hatlarını ölçeklemek için üç öneriyle kapanıyor: container eşzamanlılığını topic'in partition sayısıyla uyumlu tutun, aşağı akıştaki depolamanın yeni darboğaz haline gelmemesi için veritabanı bağlantı havuzlarını ayarlayın ve başarısız mesajlara sınırsız yeniden deneme yerine bir dead-letter hedefi tanımlayın.
Neden önemli
Consumer lag, olay güdümlü bir servisin yetersiz kaynakla çalıştığının genellikle ilk görünür belirtisidir ve Spring Boot'un hazır gelen Kafka varsayılanları verimlilik yerine basitliği tercih eder. Bu yazı, çözümün çoğu zaman mimaride değil yapılandırmada yattığının yararlı bir hatırlatıcısı: partition'larla eşleştirilmiş eşzamanlılık, gerçek işlemeye bağlı bir acknowledgment modu ve başarısız kayıtlar için bilinçli bir politika.
Somut rakamlara ise yerinde bir şüphecilikle yaklaşmak gerekir. %35'lik gecikme figürü yazarın kendi servisine ait ve yazıda lag metriği, yük verisi ya da benchmark metodolojisi paylaşılmadığından bunu genel bir beklenti değil tek bir ekibin sonucu olarak değerlendirmek gerekir. Yine de yapılandırma örüntüleri standart Spring Kafka mekanizmaları ve yüksek hacimli consumer servislerinin çoğunun ilk olarak ayarlaması gereken düğmelere doğrudan karşılık geliyor.
- #kafka
- #spring-boot
- #event-driven
- #consumer-lag
- #microservices