java
CHAPTER 94 / 99
읽기 약 2분
FUNCTION
이벤트 기반: Kafka 기초
핵심 개념
Producer/Consumer·Topic/Partition·Spring Kafka — 주문 이벤트 → 재고 감소.
본문
Kafka 핵심 개념
Topic: 메시지 분류 (예: orders, payments)
Partition: Topic 내 분할 (병렬 처리)
Producer: 메시지 발행
Consumer: 메시지 소비
Consumer Group: 같은 Topic을 함께 소비하는 그룹
특징:
- 영속성 (디스크 저장)
- 순서 보장 (Partition 내)
- 수평 확장 (Partition 추가)
- 재처리 가능 (offset reset)Spring Kafka 설정
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
acks: all # 모든 replica 확인
consumer:
group-id: order-service
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
auto-offset-reset: earliest
properties:
spring.json.trusted.packages: "com.example.event.*"Producer
public record OrderPlacedEvent(
Long orderId,
Long userId,
Long productId,
int quantity,
BigDecimal totalAmount,
LocalDateTime placedAt
) {}
@Service
@RequiredArgsConstructor
public class OrderService {
private final KafkaTemplate<String, Object> kafkaTemplate;
private final OrderRepository orderRepo;
@Transactional
public Order placeOrder(OrderRequest req) {
Order order = orderRepo.save(new Order(req));
OrderPlacedEvent event = new OrderPlacedEvent(
order.getId(), order.getUserId(),
order.getProductId(), order.getQuantity(),
order.getTotal(), LocalDateTime.now()
);
kafkaTemplate.send("orders", String.valueOf(order.getUserId()), event);
// partition key — 같은 사용자의 주문은 같은 partition (순서 보장)
return order;
}
}Consumer
@Component
@RequiredArgsConstructor
@Slf4j
public class InventoryEventListener {
private final InventoryService inventoryService;
@KafkaListener(topics = "orders", groupId = "inventory-service")
public void handleOrderPlaced(OrderPlacedEvent event) {
log.info("Order received: {}", event);
try {
inventoryService.decrementStock(event.productId(), event.quantity());
} catch (Exception e) {
log.error("재고 감소 실패: {}", event, e);
// 재시도 또는 DLQ로
throw e;
}
}
}
// 여러 Consumer Group — 같은 이벤트 다중 처리
@KafkaListener(topics = "orders", groupId = "notification-service")
public void notifyUser(OrderPlacedEvent event) {
notificationService.sendOrderConfirmation(event);
}
@KafkaListener(topics = "orders", groupId = "analytics-service")
public void recordOrder(OrderPlacedEvent event) {
analyticsService.track("order_placed", event);
}재시도와 Dead Letter Queue
@Configuration
public class KafkaConfig {
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory(
ConsumerFactory<String, Object> consumerFactory,
KafkaTemplate<String, Object> kafkaTemplate
) {
ConcurrentKafkaListenerContainerFactory<String, Object> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory);
// 재시도 + DLQ
DefaultErrorHandler errorHandler = new DefaultErrorHandler(
new DeadLetterPublishingRecoverer(kafkaTemplate),
new FixedBackOff(1000L, 3) // 1초 간격, 3회 재시도
);
factory.setCommonErrorHandler(errorHandler);
return factory;
}
}
// DLQ Listener
@KafkaListener(topics = "orders.DLT", groupId = "dlt-handler")
public void handleDeadLetter(OrderPlacedEvent event) {
log.error("Dead letter: {}", event);
// Slack 알림 + 수동 처리
}Idempotency — 중복 처리 방지
@Component
@RequiredArgsConstructor
public class OrderEventListener {
private final RedisTemplate<String, String> redis;
private final OrderProcessor processor;
@KafkaListener(topics = "orders")
public void handle(OrderPlacedEvent event) {
String key = "processed:" + event.orderId();
Boolean isNew = redis.opsForValue().setIfAbsent(key, "1", Duration.ofDays(7));
if (Boolean.FALSE.equals(isNew)) {
log.info("Already processed: {}", event.orderId());
return;
}
processor.process(event);
}
}다음 챕터
CH.26 "분산 트랜잭션: SAGA" — 보상 트랜잭션.
AI 프롬프트
🤖 AI에게 잘 물어보는 법 — 모델·전략별 프롬프트
Claude
무료: Sonnet 4.6 / Pro $20/mo: Opus 4.6
내 Spring 코드의 Kafka 이벤트 부분을 분석해서 재시도·DLQ·Idempotency와 개선 우선순위를 알려줘.
ChatGPT
무료: GPT-5.5 / Plus $20/mo: GPT-5.5 Pro
Kafka 이벤트 vs 다른 패턴 비교를 실전 사례 5개로 보여주고 Kafka vs RabbitMQ vs Kinesis를 알려줘.
Gemini
무료: 2.5 Flash / Pro $19.99/mo: 3.1 Pro
내 코드베이스 전체를 분석해서 Kafka 이벤트 관련 메시지 손실 위치를 보고해줘.
Grok
무료: Grok 4.1 / SuperGrok $30/mo
2026년 한국 기업의 Kafka 이벤트 채택률과 한국 핀테크 Kafka 활용를 솔직히 알려줘.
⭐ 이것만 기억하세요
이벤트 기반: Kafka 기초는 이 3가지만 확실히 잡으세요
1.Kafka는 영속·순서·재처리 가능 — 마이크로서비스 비동기 통신 표준
2.Producer/Consumer + Group으로 1:N 발행, Partition Key로 순서 보장
3.다음 챕터 CH.26에서 SAGA 패턴 — 분산 트랜잭션
공유하기
진행도 94 / 99