Spring, AWS SQS 표시 제한 시간 Trouble Shooting

salgu·2023년 1월 30일
1

AWS

목록 보기
7/10

환경

진행하고 있는 Notification server에서 메세징 아키텍처를 도입하여 사용하고있고
메세징 수단으로는 AWS SNS와 SQS를 사용하고있습니다.


문제

공지사항 메세지를 Notification server에 전달하여 모든 사용자에게 FCM 푸시알림을 전송하는 로직이 실행되던 중 계속해서 반복하여 공지사항이 날아가는 현상이 생겼습니다.


문제 찾기

다른 메세지 데이터들은 정상적으로 흐르고있는 것을 로그를 통해 확인을 했습니다.
SQS 콘솔을 통해 메세지를 확인해보니 Spring application에서 pulling을 하고 로직이 진행되고 있는중에 메세지가 삭제되지 않았습니다.


원인

가장 결정적이었던 원인은 SQS 설정 중에 "표시 제한 시간"이 너무 작게 설정되어 있었습니다.
기존 설정에서는 "표시 제한 시간"이 10초로 설정되어 있었고, SQS에서 메세지를 전달받아 실행되는 로직은 사용자가 점차 증가하여 20초대 가량이 소요되었기 때문입니다.

처음에 왜 10초를 했냐면 Notification Server가 스케일 아웃이 되는 상황에서도 "표시 제한 시간"이 10초면 충분히 같은 메세지를 중복 처리 하지 않겠다고 판단했기 때문입니다.

    // SQSConfig.java
    @Bean
    public ThreadPoolTaskExecutor messageThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setThreadNamePrefix("sqs-task-");
        taskExecutor.setCorePoolSize(10);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.afterPropertiesSet();
        return taskExecutor;
    }

그리고 Spring application에서 SQS Config를 다시 확인해보니 SQSListener에서 돌아가는 Thread는 Multi Thread로 돌고 있었습니다.

따라서 @SqsListener로 메세징을 받은 로직이 끝나지않아 메세지는 삭제되지 않았고
"표시 제한 시간" 설정은 10초로 지정되어 10초 뒤 메세지가 다시 표시되게 되었고
또 다른 Thread가 SQS에서 메세지를 참조하여 로직이 실행
되어 계속해서 공지사항 알림이 날아갔던 것입니다.


해결

해결방법은 2가지를 고려했습니다.

  1. "표시 제한 시간"을 로직보다 더 긴시간으로 잡아 다른 Thread가 다시 Polling 할 수 없게 설정
  2. 공지사항 보내는 로직을 비동기 처리해 메세지가 바로 삭제될 수 있게 변경

1번을 선택하면 로직은 변경되지 않아 변경이 최소화할 수 있는 장점이 있지만 로직시간이 다시 길어진다던가 장기적으론 또 다시 부채가 될 수 있을거같아 2번으로 해결하였습니다.

Spring application에서 해당 메소드를 @Async로 처리하여 비동기로 처리해주었고
Sqs Thread는 곧바로 종료되어 해당 메세지는 삭제 처리되었고 중복으로 메세지가 처리되는 현상이 해결되었습니다.

profile
https://github.com/leeeesanggyu, leeeesanggyu@gmail.com

0개의 댓글