본문 바로가기

AWS/Simple Notification Service(SNS)

3)SpringBoot SQSListner로 메세지 받기

반응형

앞에서 springboot로 sns를 발송하는것 까지 테스트 해봤다.

이제 발신된 이벤트 메세지를 AWS SNS를 구독하고 있는 SQS에 이벤트 메세지가 쌓였을것이고 지금 하고자 하는것은

이 SQS의 메세지를 springboot에서 이벤트 메세지를 내려받는 SQSListner를 구현해보고자 한다.

 

1) SNS 메세지 발송

2) 구독중인 SQS에 이벤트 메세지 쌓임.

3) SpringBoot Application에서 메세지 내려받음. ( 요부분을 구현)

 

먼저 SQS client 설정을 추가한다.

@RequiredArgsConstructor
@Configuration
public class AwsSqsListnerConfig {

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


    @Primary
    @Bean
    public AmazonSQSBufferedAsyncClient amazonSQSAws(Environment environment) {
        AmazonSQSAsync amazonSQSAsync = AmazonSQSAsyncClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(
                new BasicAWSCredentials(environment.getProperty("cloud.aws.credentials.access-key"), environment.getProperty("cloud.aws.credentials.secret-key"))))
                .withRegion(region)
                .build();

        return new AmazonSQSBufferedAsyncClient(amazonSQSAsync);
    }

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(Environment environment) {
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer();
        simpleMessageListenerContainer.setAmazonSqs(amazonSQSAws(environment));
        simpleMessageListenerContainer.setMessageHandler(queueMessageHandler(environment));
        simpleMessageListenerContainer.setMaxNumberOfMessages(10); // 최대값이 10
        simpleMessageListenerContainer.setTaskExecutor(threadPoolTaskExecutor());
        return simpleMessageListenerContainer;
    }

    @Bean
    public QueueMessageHandler queueMessageHandler(Environment environment) {
        QueueMessageHandlerFactory queueMessageHandlerFactory = new QueueMessageHandlerFactory();
        queueMessageHandlerFactory.setAmazonSqs(amazonSQSAws(environment));
        return queueMessageHandlerFactory.createQueueMessageHandler();
    }

    @Bean
    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);
        executor.setMaxPoolSize(50);
        executor.setThreadNamePrefix("sqs-test-listener-");
        executor.initialize();
        return executor;
    }
}

위 코드에서 보면 쓰레들 풀 설정이 들어가 있는데 요기서 유추해 볼수 있는게 

1) sqs 이벤트 메세지를 받을때 쓰레드가 멀티로 떠서 받아오는군아

2) 그럼 이벤트 메세지의 순서는 보장되지 않겠군아.

3) 이벤트의 시간 순서가 필요하면 이벤트 메세지의 시간정보가 꼭 필요하군아.

 

등의 분석을 할 수 있을것 같다.

 

위 설정을 추가한 후에 이제 앞에서 만들었던 SQS에 대한 Listner설정을 해보자.

package com.devracoon.awssnstest.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.aws.messaging.listener.SqsMessageDeletionPolicy;
import org.springframework.cloud.aws.messaging.listener.annotation.SqsListener;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class AwsSQSListener {

    @SqsListener(value="DevRacoon-SQS-Test" , deletionPolicy = SqsMessageDeletionPolicy.NEVER)
    public void testSqsListener(String snsMessage){
        log.info("sns message : {}" , snsMessage);
    }
}

요렇게 설정을 하고 나면 끗!

deletionPolicy에 대한것은 요기서 따로 언급 하지 않는다.

 

이렇게 하면 간단하게 메세지를 보내고 받는거 까지 완료가 되었는데. 궁금한점이 생겼다.

1) Application이 재실행 됐을때 받지 못한 메세지가 받아질까?

2) 같은 이름의 SQSListner를 가진 Applicaiton이 두개 뜬다면 어떤식으로 동작하게되는걸까?

- A , B 둘다 메세지가 잘 받아진다.

- A , B 둘중 하나만 받아진다.

- A , B 둘다 받아진다면 , A가 받고 나서 B Application이 조금 뒤에 실행된다면 메세지는 받아질까?

 

테스트 결과이다.

- A , B 둘 중 하나만 받아진다. 당연한 결과인듯 . 여러 인스턴스가 떴을때 중복 처리가 되면 안되기에~

 

참조 ) https://github.com/devraccon/AwsSNSTest.git

 

 

'AWS > Simple Notification Service(SNS)' 카테고리의 다른 글

2) Spring Boot로 AWS SNS publish 하기  (0) 2021.12.30
1) AWS SNS 설정하기  (0) 2021.11.29