AWS SQS

AWS SQS에 대해 정리합니다. 관련 아티클을 번역해 정리에 참고했습니다.

- Message Brokers
  - Apache Kafka
  - RabbitMQ
  - AWS SQS/SNS
  - 메시지 브로커를 선택할 때의 고려사항
- AWS SQS 사용해보기
  - 1. IAM 설정
  - 2. AWS에 SQS Queue 생성하기
  - 3. 의존성 추가, 기본 설정
  - 4. 메시지 발신
  - 5. 메시지 수신

Message Queue란?

메시지 큐 소프트웨어는 비동기 통신을 통해 원격으로 상호작용할 수 있도록 합니다. 이런 통신 시스템은 메시지 전송을 순차적으로 처리하는데 메시지 큐는 전송하는 응용 프로그램의 필요에 따라 응답, 요청, 또는 알람으로 구성되는 각 어플리케이션으로 유지됩니다. 메시지 소프트웨어의 장점으로는 큐를 통해 시스템이 메시지의 데이터를 분석하는데 걸리는 시간과 관계없이 시스템이 동작할 수 있기 때문에 송신자는 수신자의 응답을 기다리지 않고도 작업을 계속할 수 있다는 점이 있습니다. 단순히 비동기식 통신을 용이하는 것 외에도, 메시지 큐는 메시지를 저장, 전송 및 대기열에서 삭제하는 역할도 수행합니다. 또한 필요한 경우 메시지 정보를 문서화해서 저장할 수도 있습니다.




Message Brokers - Kafka vs RabbitMQ vs AWS SNS/SQS

MSA는 메시징 및 비동기 통신에 크게 의존합니다. 서로 통신해야 하는 서비스를 개발할 때 가장 먼저 해야 할 중요한 선택 중 하나는 적절한 메세지 브로커를 선택하는 것입니다.

Apache Kafka

image

Kafka는 아파치 소프트웨어 재단이 개발 및 관리하는 오픈 소스 메시지 브로커입니다.

주요 기능

강점과 약점




RabbitMQ

image

RabbitMQ는 Rabbit Technologies가 개발한 후 VMWare의 소유가 되었습니다.

주요 기능

강점과 약점




Amazon Web Services SQS/SNS

SNS는 여러 클라이언트(ex. 모바일 디바이스, HTTPS 엔드포인트, 다른 AWS 서비스 등)에 메시지를 신속하게 배포할 수 있는 pub-sub 모델을 제공하여 메시지 전달에 중점을 두고 있습니다. 반면 SQS는 개별 클라이언트에 의한 성공적인 메시지 전달 및 처리에 초점을 맞추고 있습니다.

주요 기능

강점과 약점




정리

image



메시지 브로커를 선택할 때의 고려사항

  1. 전송하려는 메시지의 타입
  1. 어플리케이션의 인프라 구조




Amazon SQS 사용해보기

해당 실습은 기본값으로 설정해 진행했습니다.

1. IAM 설정

image

2. AWS에 SQS Queue 생성하기

1) 세부 정보

image

image

2) 구성

image

3) 액세스 정책

image

4) 기타 - 선택 사항 (기본 - 비활성화)

image



3. 의존성 추가, 기본 설정

build.gradle

// https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-aws-messaging
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'

application 설정

cloud:
  aws:
    stack:
      auto: false
    region:
      static: ap-northeast-2
    credentials:
      access-key: [ Access Key ]
      secret-key: [ Secret Key ]
cloud.aws.stack.auto=false
cloud.aws.region.static=ap-northeast-2
cloud.aws.credentials.access-key=[Access Key]
cloud.aws.credentials.secret-key=[Secret Key]

AWS Credential 설정

import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.sqs.AmazonSQSAsync;
import com.amazonaws.services.sqs.AmazonSQSAsyncClientBuilder;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.aws.core.env.ResourceIdResolver;
import org.springframework.cloud.aws.messaging.config.SimpleMessageListenerContainerFactory;
import org.springframework.cloud.aws.messaging.core.QueueMessagingTemplate;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.messaging.converter.MappingJackson2MessageConverter;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Configuration
public class SqsMessageConfig {

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

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


    //AWS SQS에 연결해주는 클라이언트
    //해당 클라이언트를 이용하여 메세지 리스너와 전송 클라이언트를 SQS에 연동할 수 있습니다.
    @Primary
    @Bean(destroyMethod = "shutdown")
    public AmazonSQSAsync amazonSQSAws() {

        // 1) BasicAWSCredentials에 필요한 credentials를 설정하는 부분
        AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);

        return AmazonSQSAsyncClientBuilder.standard()
        

                                          // 1) ~ 3) 방법 중 하나를 골라서 사용할 수 있습니다.
                                          // 설정을 아예 안 한다면? -> DefaultAWSCredentialsProviderChain에 의해 우선순위가 가장 높은 3) 방법이 적용됩니다.

                                          // 1) BasicAWSCredentials -> 직접 코드에 넣어서 주입하는 방법
                                          .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                                          // 2) EnvironmentVariableCredentialsProvider -> 환경변수로 주입하는 방법
                                          .withCredentials(new EnvironmentVariableCredentialsProvider())
                                          // 3) InstanceProfileCredentialsProvider를 주입 후 ec2에 배포, IAM role을 어플리케이션 구동하는 ec2에 바로 부여
                                          .withCredentials(InstanceProfileCredentialsProvider.getInstance())

                                          .withRegion(Regions.AP_NORTHEAST_2)
                                          .build();
    }

    //메시지 리스너
    @Bean
    public SimpleMessageListenerContainerFactory simpleMessageListenerContainerFactory(AmazonSQSAsync amazonSQSAsync) {
        SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();

        factory.setAmazonSqs(amazonSQSAsync);
        return factory;
    }

    //메시지 전송 클라이언트
    @Primary
    @Bean
    public QueueMessagingTemplate queueMessagingTemplate(AmazonSQSAsync amazonSqs) {
        return new QueueMessagingTemplate(amazonSqs, (ResourceIdResolver) null, new MappingJackson2MessageConverter());
    }
}



4. 메시지 발신

@Service
public class SqsMessageSender {

    private final QueueMessagingTemplate queueMessagingTemplate;

    @Autowired
    public SqsMessageSender(AmazonSQS amazonSQS) {
        this.queueMessagingTemplate = new QueueMessagingTemplate((AmazonSQSAsync) amazonSQS);
    }

    public void send(String message) {
        Message<String> sendMessage = MessageBuilder.withPayload(message).build();
        queueMessagingTemplate.send("생성한 queue 이름", sendMessage);
        // 객체를 전송 할 때는 queueMessagingTemplate.convertAndSend()을 사용해 MessageConverter 인터페이스에 직렬화 책임을 위임할 수 있습니다.
    }
}



5. 메시지 수신

@Component
public class SqsMessageListener {

    @SqsListener(value = "생성한 queue 이름", deletionPolicy = SqsMessageDeletionPolicy.ON_SUCCESS)
    public void listen(@Payload String message, @Headers Map<String, String> headers) {
    }
}

SqsMessageDeletionPolicy

메시지를 받은 이후의 삭제 정책으로 네 가지가 있습니다.



6. DLQ(Dead-Letter Queue)

image

참고:

Kafka vs RabbitMQ vs AWS SNS/SQS: Which Broker to Choose?

Kafka vs ActiveMQ vs RabbitMQ vs Amazon SNS vs Amazon SQS vs Google pub/sub

AWS SQS 들이파기