13.3 대용량 트래픽을 위한 Apache Kafka 이벤트 발행/구독
Kafka는 RabbitMQ와 같은 일반 메시지 큐와 근본적으로 다릅니다. 메시지를 소비해도 즉시 삭제하지 않고 로그처럼 영구 보관 하며, 동시에 수천만 건의 이벤트를 처리하도록 설계된 분산 이벤트 스트리밍 플랫폼 입니다.
1. Kafka 핵심 개념
- Topic: 이벤트 카테고리 (예:
order-events,user-signup) - Partition: 토픽을 분할하는 단위. 파티션이 많을수록 병렬 처리 속도가 향상됩니다.
- Consumer Group: 같은 그룹 내의 컨슈머들은 파티션을 나눠서 처리합니다. (병렬 소비)
- Offset: 파티션 내에서 메시지의 위치. 컨슈머는 자신이 어디까지 읽었는지 오프셋으로 추적합니다.
2. Spring Kafka 프로듀서(Producer) 설정과 발행
implementation 'org.springframework.kafka:spring-kafka'
spring:
kafka:
bootstrap-servers: localhost:9092
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
@Service
@RequiredArgsConstructor
public class OrderEventProducer {
private final KafkaTemplate<String, OrderCreatedEvent> kafkaTemplate;
public void publishOrderEvent(OrderCreatedEvent event) {
// partition key로 orderId 사용 → 동일 주문 이벤트는 항상 동일 파티션에 순서대로 저장
kafkaTemplate.send("order-events", event.getOrderId().toString(), event);
}
}
3. 컨슈머(Consumer)와 Consumer Group
spring:
kafka:
consumer:
group-id: notification-service # 컨슈머 그룹 ID
auto-offset-reset: earliest # 메시지 소비 시작점 (earliest=처음부터, latest=최신부터)
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
properties:
spring.json.trusted.packages: "*"
@Service
@Slf4j
public class NotificationConsumer {
@KafkaListener(topics = "order-events", groupId = "notification-service")
public void handleOrderEvent(OrderCreatedEvent event) {
log.info("주문 이벤트 수신 (알림 서비스): {}", event.getOrderId());
// 이메일 / SMS / 푸시 알림 전송 로직
}
}
팁
RabbitMQ vs Kafka 선택 기준
- RabbitMQ: 빠른 작업 큐가 필요하거나, 메시지를 소비하면 사라지는 단일 서비스 로직에 적합
- Kafka: 이벤트 재처리, 여러 컨슈머 그룹이 같은 이벤트를 독립적으로 소비해야 하는 MSA 이벤트 스트리밍에 적합