ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • SMS 메시지 중복 발송(kafka 메시지 중복 발행)
    장애대응 2023. 4. 3. 00:01
    728x90

    개요

    무료 구독은 만료되면 자동으로 유료로 전환됩니다.

    이때 아직 구독 취소를 하지 않은 사용자에게 3일 전에 알림을 주기 위해 메시지를 발송하는 로직이 존재했습니다.

    어느 날, 메시지 발송이 여러번나갔다는 VOC가 인입되었으며 원인을 파악해보고자 합니다.

     

    현재 시스템 구조

    매일 오전 10시에 배치 어플리케이션에서 구독 취소를 하지 않은 사용자를 추출하여 Kafka 메시지를 발행합니다.

    이후 notification system에서 Kafka 메시지를 consume 한 뒤 SMS 메시지를 전송합니다.

     

    첫 번째 원인 파악

    SMS 메시지를 발행하는 기능은 평소에 문제없이 잘 돌아가고 있었습니다.

     

    첫 번째로 배치 애플리케이션에서 문제가 발생했을 수 있기 때문에 배치 애플리케이션의 로그를 살펴보았습니다.

    하지만 배치에서는 N명의 회원을 리스트로 묶은 발송요청을 1건만 발행했습니다.

    평소와의 차이점이라면 평소에는 100명대의 회원에게 메시지를 보냈다면 300명대의 회원에게 메시지를 보냈습니다.

     

    즉, 배치애플리케이션에서는 원인이 파악되지 않는다.

     

    두 번째 원인 파악

    notification system의 로그를 살펴보았습니다.

     

    다음과 같은 Exception이 발생했습니다.

    CommitFailedException:
    Offset commit cannot be completed since the consumer
    is not part of an active group for auto partition assignment

     

    kafka consumer 중 일부가 fail 되었다고 판단하고 rebalancing을 시도하고, 그 중간에 commit이 발생하는 경우 해당 commit은 에러 처리가 되어 위와 같은 에러가 발생합니다.

     

    kafka는 poll이 호출되는 간격이 max.poll.interval.ms(default: 5분)가 넘어가거나 heart beat가 session.timeout.ms(default: 10초) 내에 수신되지 않을 경우 해당 consumer가 죽은 것으로 판단합니다.

     

    poll에 대한 처리가 늦어져 발생할 수 있으며, heart beat가 제대로 전송되지 못한 경우도 존재합니다.

     

    실제 notification서버에서는 메시지를 한 건 보낼 때 sleep으로 1초 동안 대기하는 로직이 존재합니다.

    (자세한 히스토리는 파악해야 겠지만 초당 1건 발송으로 제한이 걸려있는 것 같습니다.)

     

    또한 max_poll_records(메시지를 당겨오는 것에 대한 최대 메시지 수)가 500으로 설정되어 있습니다.

    동시에 처리하는 kafka 메시지 수가 늘어나면 처리하는 시간이 늘어나 exception 발생 가능성이 높아집니다.

     

    결과적으로 300명대의 회원에게 메시지를 발송하던 중 Exception이 발생하면서 예외가 발생하기 전에 회원들은 반복적으로 메시지를 받고 있었던 것입니다.

     

    추후 대처

    • 실제 notification에서 발송이 실패 나고 있는지 알림이 필요하다
    • Batch 애플리케이션에서 토픽 메시지의 사이즈를 50건으로 쪼개서 보내기(+ 메시지 발생 중간 1분 delay 추가)
    • kafka config 설정에서 max_pool_records = 1으로 설정

     

     

     

     

     

     

    댓글

Designed by Tistory.