Kafka, Redis를 활용한 이벤트 중복 처리 방지

2024. 12. 19. 00:31·이슈

2차 팀프로젝트 회고

주문 서비스와 배송 서비스 간 Kafka 사용

네트워크 지연, 시스템 장애 등으로 인한 메시지 중복 전송이나 순서 보장 문제가 발생할 수 있는 문제에 대한 고민

 

구성

- 메시지 큐: Kafka
- 중복 처리 방지: Redis
- 이벤트 타입: OrderCreateEvent (주문 생성 이벤트)


1. 이벤트 중복 처리 방지

@KafkaListener(
            topics = "${spring.kafka.consumer.topic.order.create}", // OrderCreateEvent
            groupId = "${spring.kafka.consumer.group-id}", // group-delivery
            containerFactory = "orderCreateEventListener"
    )
    public void consumeOrderCreateEvent(DomainEventEnvelop<OrderCreateEvent> eventEnvelop) {
        OrderCreateEvent orderCreateEvent = eventEnvelop.getEvent();
        Long orderId = orderCreateEvent.getOrderId();
        LocalDateTime createdAt = eventEnvelop.getCreatedAt();
        String eventKey = EVENT_KEY_PREFIX + orderId;

        // 현재 이벤트가 기존 이벤트보다 과거이거나 같은 시간이면 무시
        String existingEventTimestamp = redisTemplate.opsForValue().get(eventKey);
        if (existingEventTimestamp != null) {
            LocalDateTime existingCreatedAt = LocalDateTime.parse(existingEventTimestamp);
            if (!createdAt.isAfter(existingCreatedAt)) {
                log.warn("과거 이벤트 발생 [orderId: {}, currentEventTimestamp: {}, existingEventTimestamp: {}" , orderId, createdAt, existingCreatedAt);
                return;
            }
        }

Redis를 활용하여 주문아이디와 이벤트의 타임스탬프 정보를 저장하였고 동일한 주문 아이디에 대해 이전 이벤트보다 과거의 이벤트가 들어오면 무시

2. 이벤트 정보 저장

redisTemplate.opsForValue().set(eventKey, createdAt.toString(), Duration.ofDays(1));

 

이벤트 정보를 Redis에 1일간 보관, TTL설정을 어떻게 하면 좋을지 판단이 안되었다.

 

3. 배송 생성 

try {
    deliveryService.createDelivery(DeliveryCreateRequestDto.from(orderCreateEvent));
} catch (Exception e) {
    log.error("Failed to process OrderCreateEvent - orderId: {}, error: {}",
            orderCreateEvent.getOrderId(), e.getMessage(), e);
    throw new RuntimeException(e);
}

 

유효한 이벤트에 대해 배송 생성 하며 예외 발생 시 로그 기록

 

데이터베이스 기반 중복 처리 방법

따로 이벤트 발생되는 로그를 테이블에 저장 후 값을 읽어와도 될 거같다.

 

DB 부하 증가, 이벤트 처리 지연 시간 증가의 문제가 있다는것을 예상은 하지만 트래픽이 얼만큼 발생되느냐에 따라 다를거같다. 또 아직 그만큼의 트래픽은 경험해보지 못해서 이번에 비교 성능테스트를 하지못한 점은 아쉽다.

 

이벤트 발생 정보를 레디스로 저장 후 휘발 시킬것인가? 로그까지 저장할 것인가에 대한 고민은 해결되지 않았다.

 

'이슈' 카테고리의 다른 글

상품 재고 관리 - 비관적 락 vs 분산 락 적용 사례  (2) 2025.01.31
RDB vs Elasticsearch 검색 성능 비교  (0) 2025.01.10
[Jenkins] 용량 부족 - EBS 볼륨 연결  (0) 2024.11.19
AWS EC2 배포 작업  (0) 2023.09.07
데이터 설계에 대한 고민  (0) 2023.07.28
'이슈' 카테고리의 다른 글
  • 상품 재고 관리 - 비관적 락 vs 분산 락 적용 사례
  • RDB vs Elasticsearch 검색 성능 비교
  • [Jenkins] 용량 부족 - EBS 볼륨 연결
  • AWS EC2 배포 작업
유당불내증이 있는 개발자
유당불내증이 있는 개발자
  • 유당불내증이 있는 개발자
    보초개발
    유당불내증이 있는 개발자
  • 전체
    오늘
    어제
    • 분류 전체보기
      • DB
      • Java
      • 이슈
      • 책
        • 객체지향의 사실과 오해
        • 자바의 신
        • 스프링 입문을 위한 자바 객체 지향의 원리와 이해
        • 토비의 스프링
        • 모던 자바 인 액션
        • 이펙티브 자바
        • Real MySQL 8.0
        • 자바 성능 튜닝이야기
        • 만들면서 배우는 클린 아키텍처
      • 인프런 강의
        • Practical Testing: 실용적인 테스트..
        • Jenkins를 이용한 CICD Pipeline ..
        • 비전공자도 이해할 수 있는 쿠버네티스 입문,실전
        • 대기업 근무하며 경험한 Redis를 야무지게 사용..
      • TIL
  • 인기 글

  • 태그

    EC2
    MySQL
    db
    explain
    AWS
    redis
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
유당불내증이 있는 개발자
Kafka, Redis를 활용한 이벤트 중복 처리 방지
상단으로

티스토리툴바