본문 바로가기

Back-end/Spring

[Spring Cloud] Messaging - SQS(Simple Queue Service)

SpringBoot 프로젝트에서 SQS 메시지를 전달하고 받는 실습을 진행해보겠습니다.

 

SQS는 AWS에서 제공하는 메시지 대기열 서비스로서 대기열(Queue)을 이용하면 메시지를 순차적으로 저장할 수 있으며 대기열에 저장된 메시지는 별로의 프로세스에서 작업을 진행할 수 있습니다.

 

주로 1:1 관계로 매핑되는 작업에서 많이 사용됩니다.

 

예를 들면 회원 가입 후 가입완료 메일 발송, 고객 주문 완료 후 배송 처리와 같이 주 프로세스가 완료된 이후 추가적으로 발생하는 작업 처리를 위해 많이 사용됩니다.

또는 서비스에 대량의 이벤트가 발생할 때 Queue를 이용하면 작업이 예약되어 처리되기 때문에 대량의 요청에서도 안정적인 시스템을 운용할 수 있게 됩니다.

 

참고로 동일한 메세지를 다수가 받아야 하는 (1:N) 작업일 경우엔 AWS에서 제공하는 아래 서비스 중 하나를 사용하면 됩니다.

  • SNS(Simple Notification Service)
  • MSK(Amazon Managed Streaming For Apache Kafka)
  • Kinesis(Amazon Kinesis Data Streams)

 

 

SpringBoot에서 SQS 사용하기

 

Spring Cloud 라이브러리를 이용하면 예제의 코드처럼 간단하게 Sender, Listener 구현이 가능합니다.

 

import com.amazonaws.services.sqs.AmazonSQS;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener;
import org.springframework.messaging.Message;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class MessageProcessor {

    private final String queueName = "event-collect";
    private QueueMessagingTemplate queueMessagingTemplate;

    @Autowired
    public MessageProcessor(AmazonSQS amazonSqs) {
        this.queueMessagingTemplate = new QueueMessagingTemplate((AmazonSQSAsync) amazonSqs);
    }

    public void send(String data) {
        Message<String> message = MessageBuilder.withPayload(data).build();
        queueMessagingTemplate.send(queueName, message);
    }

    @SqsListener(value = queueName)
    public void receive(String message) {
        log.info("Event : {}", message);
    }
}

 

 

@SqsListener 메시지 삭제 정책

 

Listener에는 4가지 메시지 삭제 정책 (Sqs Message Deletion Policy)이 있습니다.

 

  • ALWAYS: 리스너 메서드에 의한 메시지 처리 중 성공 (예외 발생 없음) 또는 실패 (예외 발생) 시 항상 메시지를 삭제합니다.
  • NEVER: 메시지를 자동으로 삭제하지 않습니다. 수신 확인(Acknowledgement)로 명시적으로 삭제가 가능합니다.
  • NO_REDRIVE: Redrive Policy(DeadLetterQueue)가 정의되지 않은 경우 메시지를 삭제합니다. (default)
  • ON_SUCCESS: 리스너 메서드에 의해 성공적으로 실행되면 메시지를 삭제합니다.

 

정책을 적용하려면 다음과 같이 @SqsListener에 설정을 추가하면 됩니다. 명시적으로 선언하지 않으면 NO_REDRIVE가 기본 정책으로 사용됩니다.

 

@SqsListener(value = queueName, deletionPolicy = SqsMessageDeletionPolicy.NEVER)
public void receive(String message) {
    log.info("Event : {}", message);
}

 

 

참고: https://daddyprogrammer.org/post/14825/spring-cloud-messaging-sqs/