들어가기 전..
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
보낼 수 있는 크기의 제한..?
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으로 날려보자.
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://aws.amazon.com/ko/sqs/pricing/
https://spring.io/projects/spring-cloud-aws
'인프라' 카테고리의 다른 글
EC2를 이용한 AWS ECS 기반 Spring Boot 3 DataDog 적용 (1) | 2024.10.03 |
---|---|
기본적인 AWS VPC 구성기 (0) | 2024.07.27 |
AWS Bedrock + Spring Boot + Amazon Bedrock Guardrails를 이용해 간단한 AI 사용해보기 (3) | 2024.06.16 |
AWS SNS과 FCM 그리고 Spring Boot를 곁들인.. (0) | 2024.05.08 |
Linode Objects Storage 구성 및 Spring Cloud aws와 연동 (0) | 2023.07.12 |