본문 바로가기
회고/TIL

[TIL] 2025.12.18

by 세류오 2025. 12. 18.

카프카 리스너의 구조 알아보기

@KafkaListener( 
   topics = "order-events", 
   groupId = "stock-consumer-group", 
   containerFactory = "kafkaListenerContainerFactory" 
   )

1. topics = "order-events"

Consumer가 구독 할 Kafka 토픽의 이름
order-events 토픽을 메시지로 소비한다
왜 필요한가?

  • Kafka는 토픽 기반의 Pub/Sub 모델이기 때문이다
  • Producer -> [order-events] -> Consumer
  • 이 값이 없다면 어떤 메시지를 들어야 할지 모르기 때문에 Consumer는 아무것도 못받는다

토픽은 하나이상 가능하다

  • topics = {"order-events", "payment-events"}

2. groupId = "stock-consumer-group"

카프카 Consumer Group ID를 나타낸다
이 Listener가 어떤 consumer 그룹에 속하는지를 나타냄
왜 필요한가?

  • Kafka의 병렬처리, 중복 소비 방지의 핵심개념이 바로 Consumer Group
  • 같은 groupId를 쓰는 Consumer들은 아래와같은 특징을 가진다
    • 메시지를 나눠서 처리한다
    • 한 메시지는 그룹 내 Consumer 중 단 한 개만 처리한다.
    • 다른 groupId를 쓰는 Consumer들은 같은 메시지를 각자 모두 받는다.
같은 그룹일 경우(재고 처리)
-> 주문 이벤트가 A또는 B 중 하나에게만 전달된다
order-events
 ├─ Consumer A (group=stock)
 └─ Consumer B (group=stock)
다른 그룹일 경우(재고처리, 알림)
-> 재고 서비스도 받고, 알림 서비스도 받는다
order-events
 ├─ Consumer (group=stock)
 └─ Consumer (group=notification)

3. containerFactory = "kafkaListenerContainerFactory"

이 Listener를 실행할 KafkaListenerContainer의설정 Bean의 이름
어떤 Consumer 설정으로 이 Listener를 띄울 지 를 지정한다
왜 필요한가?

  • Spring Kafka는 내부적으로
    "Listener 하나 당 Consumer컨테이너" 를 띄운다
  • 컨테이너에는 아래와 같은 설정들이 필요하다
    • Deserializer(String? JSON?)
    • Ack Mode(자동 커밋? 수동 커밋?
    • Concurrency(Consumer스레드의 개수)
    • Error Handler
    • Retry / DLQ설정
      이것을 containerFactory로 분리하여 관리한다

만약 사용하지 않으면?

  • 기본설정(kafkaListenerContainerFactory)이 자동으로 사용됨
  • 단일타입 Consumer만 있을 때는 괜찮다
  • 하지만 실제 사용시에
    • JSON Consumer
    • Retry 전용 Consumer
    • DLQ consumer
      등 여러 설정이 필요하며 반드시 분리해야한다.

'회고 > TIL' 카테고리의 다른 글

[TIL] 2025.12.25 TDD에 대한 학습  (0) 2025.12.26
[TIL] 2025.12.19  (0) 2025.12.20
[TIL] 2025.12.10  (0) 2025.12.10
[TIL] 2025.09.30 화요일  (0) 2025.10.01