SQS를 스프링부트에서 사용해보자!

dev-jjun·2023년 8월 13일
0

Server

목록 보기
22/33

STEP1. 대기열 생성

자, 먼저 AWS의 SQS 페이지로 들어가 [대기열 생성]을 클릭하자!
AWS SQS 대기열 생성하러 가봅시다 ~!~!~!

1-1. 세부 정보

표준 대기열

  • 속도 - 무제한
    • 초당 호출 수 제한 거의 X
  • 최대한 도착한 순서대로 처리하도록 정렬하지만 완전한 보장은 X
  • 높은 처리량을 위해 설계
  • 메시지 큐에 쌓여 있는 메시지를 최소 1회 전송하지만, 가끔 한 개 이상의 메시지 사본이 배달될 수도 있다 ⇒ 중복 메시지 발생 가능

FIFO 대기열

  • 속도 - 300~3000msg/s의 제한 有
    • API - 초당 최대 300개
    • 배치함수 - 초당 최대 3000개의 메시지 처리 가능
  • 비즈니스 로직에서 메시지 발행 순서가 반드시 보장되어야 하는 경우에 사용
  • 정확히 1회만 전송 ⇒ 중복 메시지 발생 X

→ 필요에 따라 유형을 선택한 후, 대기열의 이름을 지정해주자

👨‍👩‍👧‍👦 엄빠도 어렸다에서는요?

일단 메시지를 보내는 순서가 유지되어야 한다는 개념이 각 부모자식 관계마다 일정시간에 알림을 예약해두는 스케줄링 작업에도 적용되는지 확실하지 않아,

표준 대기열로 선택을 해보겠다

1-2. 구성 설정

  • 표시 제한 시간 한 메시지 소비자가 대기열에서 푸시 받은 메시지를 다른 메시지 소비자에게는 보이지 않는 시간 ⇒ 즉, 하나의 소비자에게만 메시지가 푸시되는 동안 다른 소비자에게는 푸시하지 않도록 간격을 보장한다.
  • 메시지 보존 기간 SQS가 삭제되지 않은 메시지를 보관하는 시간 ⇒ 일정 시간 동안 보관해두었다가 사라진다.
  • 전송 지연 대기열에 추가된 각 메시지의 첫 번째 전송에 대한 지연시간 *일부러 전송을 늦추고 싶다면 이 부분을 바꿔주면 된다.
  • 최대 메시지 크기 전송하려는 메시지의 최대 크기 *256KB가 최대이며, 이를 넘어가는 경우에는 Amazon SQS Extended Client Library를 사용해 S3와 함께 사용할 수 있다.
  • 메시지 수신 대기 시간 Polling이 메시지를 사용할 수 있을 때까지 기다리는 최대 시간

→ 일단 default로 지정된 값대로 아무것도 건드리지 않고 생성해보겠다!

1-3. 암호화 및 권한 설정

*여기서는 암호화만 비활성화 해두고, 기본 설정 그대로 건드리지 않는다.

서버 측 암호화(SSE, Server Side Encryption)를 활성화하면 SQS는 대기열에 들어오는 모든 메시지들을 암호화한다. 따라서 권한을 가진 소비자에게 전송되는 경우에만 메시지 해독이 가능하다.

따라서, 일단은 암호화를 비활성화 하고 넘어가도록 하자

대기열에 접근할 수 있는 액세스 정책에 대한 내용인데, 이는 기본 설정값 그대로 유지하고, IAM 쪽에서 AWS의 접근권한을 설정하는 것으로 하겠다.

배달 못한 편지 = DLQ는 메시지를 소비할 수 없을 때 사용되며, 이를 통해 문제가 발생한 메시지를 격리하여 실패 원인을 분석할 수 있다.

이렇게 대기열을 생성하고, 메시지 전송 및 수신 테스트를 해서 성공하면 정상적으로 SQS가 생성된 것이다.

아무런 문자열이나 입력한 후(json, string 형식 모두 가능) [메시지 전송]을 클릭하면 아래와 같이 [메시지 폴링] 버튼이 활성화되고,

클릭하면 대기열에 쌓여있던 메시지가 폴링된 것을 볼 수 있다.

STEP2. IAM 사용자 생성 및 키 발급

AWS IAM 사용자 생성 Go~!

2-1. 사용자 세부 정보 지정

AWS IAM > 사용자 > [사용자 추가]를 클릭하여 SQS에 권한을 갖는 IAM 사용자를 생성한다.

2-2. 권한 설정

‘직접 정책 연결’ 선택 후, AmazonSQSFullAccess 권한을 적용한다.

2-3. 보안 자격 증명 > 액세스 키 발급

액세스 키 만들기를 클릭하면, 아래와 같은 액세스 키 모범 사례 및 대안정보 선택사항이 뜨는데 아래와 같이 설정해주고 넘어간다.

액세스 키를 생성하면 아래와 같이 액세스 키, 비밀 액세스 키가 뜨는데 이는 다시 볼 수 없으니 꼭 다른 데 까먹지 않게 기록해두자!

STEP3. 스프링부트 프로젝트 설정

Spring Cloud AWS(스프링 3.0 버전 이상에 적용되는 공식문서)

build.gradle에 의존성 추가

// AWS SQS
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-messaging', version: '2.2.6.RELEASE'
implementation group: 'org.springframework.cloud', name: 'spring-cloud-aws-autoconfigure', version: '2.2.6.RELEASE'

// Spring 3.0 버전 이상이라면 아래로 설정
implementation platform("io.awspring.cloud:spring-cloud-aws-dependencies:3.0.1")
implementation 'io.awspring.cloud:spring-cloud-aws-starter-sqs'

application.yml

cloud:
  aws:
    region:
      static: ap-northeast-2
    credentials:
      access-key: {IAM 액세스 키}
      secret-key: {IAM 시크릿 액세스 키}
    sqs:
      queue-name: {SQS 대기열 이름}
    stack:
      auto: false

테스트용 클래스

공식문서와 블로그 자료를 참고해서 테스트용 서비스, 컨트롤러 클래스를 생성하였다.

AwsSQSConfig.java

@Import(SqsBootstrapConfiguration.class)
@Configuration
public class AwsSQSConfig {

    @Value("${spring.cloud.aws.credentials.access-key")
    private String AWS_ACCESS_KEY;

    @Value("${spring.cloud.aws.credentials.secret-key")
    private String AWS_SECRET_KEY;

    @Value("${spring.cloud.aws.region.static")
    private String AWS_REGION;

    // 클라이언트 설정: region과 자격증명
    @Bean
    public SqsAsyncClient sqsAsyncClient() {
        return SqsAsyncClient.builder()
                .credentialsProvider(() -> new AwsCredentials() {
                    @Override
                    public String accessKeyId() {
                        return AWS_ACCESS_KEY;
                    }

                    @Override
                    public String secretAccessKey() {
                        return AWS_SECRET_KEY;
                    }
                })
                .region(Region.of(AWS_REGION))
                .build();
    }

    // Listener Factory 설정 (Listener 쪽)
    @Bean
    public SqsMessageListenerContainerFactory<Object> defaultSqsListenerContainerFactory() {
        return SqsMessageListenerContainerFactory.builder()
                .sqsAsyncClient(sqsAsyncClient())
                .build();
    }

    // 메시지 발송을 위한 SQS 템플릿 설정 (Sender 쪽)
    @Bean
    public SqsTemplate sqsTemplate() {
        return SqsTemplate.newTemplate(sqsAsyncClient());
    }
}
@Configuration
public class AwsSQSConfig {

	@Value("${cloud.aws.credentials.accessKey}")
	private String accessKey;

	@Value("${cloud.aws.credentials.secretKey}")
	private String secretKey;

	@Value("${cloud.aws.region.static}")
	private String region;

	@Primary
	@Bean
	public AmazonSQSAsync amazonSQSAsync() {
		BasicAWSCredentials basicAwsCredentials = new BasicAWSCredentials(accessKey, secretKey);
		return AmazonSQSAsyncClientBuilder.standard()
			.withRegion(region)
			.withCredentials(new AWSStaticCredentialsProvider(basicAwsCredentials))
			.build();
	}
}

SqsTransferListener.java

import io.awspring.cloud.sqs.annotation.SqsListener;
import org.springframework.stereotype.Component;

@Component
public class SqsTransferListener {

    @SqsListener("${spring.cloud.aws.sqs.queue-name}")
    public void messageListener(String message) {
        System.out.println("Listener: " + message);
    }
}

SqsMessageSender.java

import io.awspring.cloud.sqs.operations.SendResult;
import io.awspring.cloud.sqs.operations.SqsTemplate;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.services.sqs.SqsAsyncClient;

@Component
public class SqsMessageSender {

    private final SqsTemplate queueMessagingTemplate;

    @Value("${spring.cloud.aws.sqs.queue-name}")
    private String QUEUE_NAME;

    public SqsMessageSender(SqsAsyncClient sqsAsyncClient) {
        this.queueMessagingTemplate = SqsTemplate.newTemplate(sqsAsyncClient);
    }

    public SendResult<String> sendMessage(String message) {
//        Message<String> newMessage = MessageBuilder.withPayload(message).build();
        System.out.println("Sender: " + message);
        return queueMessagingTemplate.send(to -> to
                .queue(QUEUE_NAME)
                .payload(message));
    }
}

참고 자료

AWS SQS 들이파기

Spring boot 3.x + Amazon SQS 적용기

profile
서버 개발자를 꿈꾸며 성장하는 쭌입니다 😽

0개의 댓글