인프라

AWS SQS 256KB 이상 대용량 메시지 처리와 Spring Boot

dev.Dove 2024. 7. 6. 15:29

출처: https://aws.amazon.com/ko/sqs/

들어가기 전..

Spring Boot 3.3.1(Java 17)을 기준으로 구현했습니다.

2024년 7월 기준 AWS SQS 대용량 전송 라이브러리는 Java, Python만 있습니다.

 

소스는 GitHub에서 확인 가능합니다.
https://github.com/Dove-kim/spring-boot-3-aws-sqs-bigmessage 

 

GitHub - Dove-kim/spring-boot-3-aws-sqs-bigmessage: AWS SQS에서 256KB 이상의 메시지 전송 기능 구현

AWS SQS에서 256KB 이상의 메시지 전송 기능 구현. Contribute to Dove-kim/spring-boot-3-aws-sqs-bigmessage development by creating an account on GitHub.

github.com


보낼 수 있는 크기의 제한..?

출처: https://aws.amazon.com/ko/sqs/features/

 

AWS SQS 완전 관리형에 백만건당 요금을 부과하기에 꽤 저렴하다.

하지만.. 큰 메시지를 보낼 때는 제약이 있고 AWS는 S3를 이용해 큰 메시지를 전송하도록 안내한다.

 

다행히 Java는 라이브러리를 제공해 준다. 라이브러리를 사용하면 큰 용량의 메시지도 편리하게 보낼 수 있다.

단점으로는 S3를 추가로 사용하는 이유로  S3 저장비용과 데이터를 가져오는 비용을 감수해야 한다.

 

 

간단한 SQS와 S3 만들기

1. 원하는 이름의 표준 대기열을 하나 만든다.

 

2. 메시지 동시 처리를 막기 위해 표시 제한 시간과 기타 설정값을 세팅한다.

 

3. 다른 설정은 변경 없이 "대기열 생성" 버튼 클릭

 

4. S3 버킷을 만든다.

 


스프링에서 SQS 확장 클라이언트 라이브러리 적용해 보기

 1. build.gradle 수정

https://spring.io/projects/spring-cloud-aws보다 AWS SDK를 직접 사용하는 것을 개인적으로 선호합니다.
implementation platform("software.amazon.awssdk:bom:2.21.1")
implementation "software.amazon.awssdk:sqs"
implementation "software.amazon.awssdk:s3"

implementation 'com.amazonaws:amazon-sqs-java-extended-client-lib:2.1.1'

 

2. S3, SQS  클라이언트 bean 등록

DefaultCredentialsProvider.create()를 통해 서버가 기동 되는 환경에서 AWS CLI나 IAM 역할로 서버에게 AWS 접근을 가능하게 도와준다.

@Configuration
public class AwsConfig {

    @Bean
    public SqsClient sqsClient() {
        return SqsClient.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();
    }

    @Bean
    public S3Client s3Client() {
        return S3Client.builder()
                .region(Region.AP_NORTHEAST_2)
                .credentialsProvider(DefaultCredentialsProvider.create())
                .build();
    }
}

 

 

3. AWS SQS 확장 라이브러리 클라이언트에 사전에 만든 S3를 세팅한다.

ExtendedClientConfiguration extendedClientConfig = new ExtendedClientConfiguration()
	.withPayloadSupportEnabled(s3Client, BUCKET_NAME);
this.sqsExtended = new AmazonSQSExtendedClient(SqsClient.builder().build(), extendedClientConfig);

 

4. SQS에서 메시지를 풀링 한다.

// SQS queue url
this.queueUrl = sqsClient.getQueueUrl(builder -> builder
        .queueName(SQS_QUEUE_NAME).build());
ReceiveMessageRequest receiveMessageRequest = ReceiveMessageRequest.builder()
                .queueUrl(queueUrl.queueUrl())
                .maxNumberOfMessages(10)
                .waitTimeSeconds(0)
                .build();
        
ReceiveMessageResponse receiveMessageResponse = sqsExtended
	.receiveMessage(receiveMessageRequest);

 

5. 읽고 처리한 메시지는 지운다.

DeleteMessageRequest deleteMessageRequest = DeleteMessageRequest.builder()
                .queueUrl(queueUrl.queueUrl())
                .receiptHandle(message.receiptHandle())
                .build();
sqsExtended.deleteMessage(deleteMessageRequest);

질문 1. S3는 어떻게 작동을 도와줄까?

간단하게 메시지를 publish 할 수 있는 컨트롤러를 만들고 postman으로 날려보자.

간단한 컨트롤러에 약 353KB의 메시지 전송

 

IDE에서 브레이크 포인트로 메시지 처리를 멈추고

 

S3에 가보니, 전송한 데이터가 파일로 만들어져 있다.

열어보니, 전송한 내용이다.

이후 SQS client를 이용해 SQS 메시지를 지우면 S3에 있던 데이터도 같이 지워진다.


질문 2. 256KB보다 작은 사이즈의 메시지도 S3가 관여하는가?

PayloadStorageConfigurationBase에서 AmazonSQSExtendedClient를 세팅할 때 항상 S3를 사용할지 옵션이 있다.

 

AmazonSQSExtendedClient는 설정 값에 따라 설정이 false이면, 메시지의 크기에 맞춰 S3를 사용할지 결정한다.

 

즉, 라이브러리에서 256KB보다 작은 메시지는 SQS만 이용하고 256KB보다 클 경우만 S3에 메시지를 저장하고 사용한다.


질문 3. SQS에서는 일정 시간이 지나면 처리 못한 메시지가 사라지는데 S3도 사라지게 할 수 있을까?

S3 버킷에서 수명주기를 설정하면 SQS에서 메시지 보존 기간만큼 S3에서도 파일을 저장할 수 있다.

 


참고한 문서

https://docs.aws.amazon.com/ko_kr/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-s3-messages.html

 

자바와 아마존 S3를 사용하여 대용량 Amazon SQS 메시지 관리 - Amazon Simple Queue Service

Java용 Amazon SQS 확장 클라이언트 라이브러리를 사용하면 Amazon S3에 AWS SDK for Java만 사용하여 Amazon SQS 메시지를 관리할 수 있습니다. Amazon SQS 콘솔 AWS CLI, Amazon SQS HTTP API 또는 기타 SDK로는 이 작업을

docs.aws.amazon.com

https://aws.amazon.com/ko/sqs/pricing/

 

Amazon SQS 요금 | 메시지 대기열 서비스 | AWS

* 프리 티어 사용량은 매달 GovCloud 리전을 제외한 모든 리전의 사용량을 합산하여 계산되며, 청구서에 자동으로 적용됩니다. 사용되지 않은 프리 티어는 다음 달로 이월되지 않습니다. 제약 조건

aws.amazon.com

https://spring.io/projects/spring-cloud-aws

 

Spring Cloud for Amazon Web Services

Spring Cloud for Amazon Web Services is a community-run project. The website is https://awspring.io/ and the source repository is located at https://github.com/awspring/spring-cloud-aws. Spring Cloud for Amazon Web Services, eases the integration with host

spring.io