[spring-cloud-aws] 메시지 단위로 VisibilityTimeout 변경하기

by 스뎅(thDeng) on

Visibility timeout

AWS SQS에는 메시지를 꺼내오고 명시적으로 지우지 않으면 (ack를 보내지 않으면) 일정 시간(VisibilityTimeout) 뒤에 메시지가 다시 나온다. Queue 설정에서 Default Visibility Timeout을 설정해 주면 된다.

이걸 이용해서 메시지를 정상적으로 처리하지 못 한 경우 일정 시간 후에 재처리를 하도록 설정할 수도 있다. 하지만 간혹 특정 예외의 경우는 해당 메시지만 큐에서 늦게 꺼내고 싶을 때가 있다. 예를 들어, SQS에서 메시지를 꺼내 외부 연동도 하고 다른 일들을 하는 모듈이 있는데, 외부 연동이 실패하는 경우에만 SQS에서 조금 더 나중에 꺼내서 재시도 하고 싶을 수 있다. 특성상 한 번 실패하면 바로 재시도 하면 또 실패할 확률이 높은 외부 연동이라면 한참 뒤에 재시도를 하고 싶을 수 있다.

이럴 때는 메시지 마다 VisibilityTimeout을 바꿔주면 된다.

Setting Visibility Timeout with spring-cloud-aws

메시지를 처리하다 실패했을 때, 해당 메시지의 VisibilityTimeout만 바꾸고 싶으면 Visibility를 사용하면 된다. (org.springframework.cloud.aws.messaging.listener.Visibility#extend(int seconds))

@SqsListener(value = "leocat-queue", deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void handleBizmoneyBillingEvent(@Payload OrderEvent event,
                                       MessageHeaders headers,
                                       Acknowledgment ack,
                                       Visibility visibility) {

    try {
        doSomething();
        ack.acknowledge();
    } catch (NeedLongDelayException e) {
        // 120초 message visibility timeout 설정
        visibility.extend(120);
    } catch (Exception e) {
        // 어이쿠.. 실패했네..
        // SQS queue의 Default Visibility Timeout 이후에 메시지 다시 나옴
    }
}

참고

별도로 명시하지 않을 경우, 이 블로그의 포스트는 다음 라이선스에 따라 사용할 수 있습니다: Creative Commons License CC Attribution-NonCommercial-ShareAlike 4.0 International License