자, 먼저 AWS의 SQS 페이지로 들어가 [대기열 생성]을 클릭하자!
AWS SQS 대기열 생성하러 가봅시다 ~!~!~!
→ 필요에 따라 유형을 선택한 후, 대기열의 이름을 지정해주자
👨👩👧👦 엄빠도 어렸다에서는요?일단 메시지를 보내는 순서가 유지되어야 한다는 개념이 각 부모자식 관계마다 일정시간에 알림을 예약해두는 스케줄링 작업에도 적용되는지 확실하지 않아,
표준 대기열로 선택을 해보겠다
→ 일단 default로 지정된 값대로 아무것도 건드리지 않고 생성해보겠다!
*여기서는 암호화만 비활성화 해두고, 기본 설정 그대로 건드리지 않는다.
서버 측 암호화(SSE, Server Side Encryption)를 활성화하면 SQS는 대기열에 들어오는 모든 메시지들을 암호화한다. 따라서 권한을 가진 소비자에게 전송되는 경우에만 메시지 해독이 가능하다.
따라서, 일단은 암호화를 비활성화 하고 넘어가도록 하자
대기열에 접근할 수 있는 액세스 정책에 대한 내용인데, 이는 기본 설정값 그대로 유지하고, IAM 쪽에서 AWS의 접근권한을 설정하는 것으로 하겠다.
배달 못한 편지 = DLQ는 메시지를 소비할 수 없을 때 사용되며, 이를 통해 문제가 발생한 메시지를 격리하여 실패 원인을 분석할 수 있다.
이렇게 대기열을 생성하고, 메시지 전송 및 수신 테스트를 해서 성공하면 정상적으로 SQS가 생성된 것이다.
아무런 문자열이나 입력한 후(json, string 형식 모두 가능) [메시지 전송]을 클릭하면 아래와 같이 [메시지 폴링] 버튼이 활성화되고,
클릭하면 대기열에 쌓여있던 메시지가 폴링된 것을 볼 수 있다.
AWS IAM > 사용자 > [사용자 추가]를 클릭하여 SQS에 권한을 갖는 IAM 사용자를 생성한다.
‘직접 정책 연결’ 선택 후, AmazonSQSFullAccess 권한을 적용한다.
액세스 키 만들기를 클릭하면, 아래와 같은 액세스 키 모범 사례 및 대안정보 선택사항이 뜨는데 아래와 같이 설정해주고 넘어간다.
액세스 키를 생성하면 아래와 같이 액세스 키, 비밀 액세스 키가 뜨는데 이는 다시 볼 수 없으니 꼭 다른 데 까먹지 않게 기록해두자!
Spring Cloud AWS(스프링 3.0 버전 이상에 적용되는 공식문서)
// 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'
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));
}
}