
자, 먼저 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.javaimport 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.javaimport 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));
    }
}