AWS SQS를 스프링부트에 활용하기

변현섭·2023년 8월 2일
1
post-thumbnail

AWS SQS에 대해서는 아래의 포스팅에서 간략하게 다룬 적이 있는데요.
>> AWS SQS 설명
AWS SQS는 어느덧 백엔드 개발자가 몰라서는 안 될 기술스택이 되어버린 것 같습니다. 그래서 이번 포스팅에선 AWS SQS에 대해 더 자세히 알아보고, 실제로 사용하는 방법까지 알아보도록 하겠습니다.

1. 개념

AWS SQS란, Simple Queue Service의 약자로, 분산 시스템을 구성할 때, 시스템 간 메시지를 주고 받을 수 있는 메시지 큐의 역할을 수행한다. AWS SQS는 전송, 수신, 삭제의 3가지 기능을 제공한다. 아래는 SQS의 기본 아키텍쳐를 나타낸 것이다.

Sever 측에서 보낸 요청은 Queue에 저장되고 Worker 측에서 이를 수신하여, 작업을 처리한다. Worker 측에서 작업을 마친 경우 Queue에서 메시지를 삭제할 것을 요청한다. 이것은 마치 계산원(Server)이 주문받은 메뉴를 주문판(Buffer)에 꽂아 놓으면, 바리스타(Worker)가 이를 가져가 주문에 맞는 음료를 고객에게 제공한 후, 완료된 주문을 주문판에서 빼버리는 것과 같다.

스프링으로 구현된 서버 코드에서, 파이썬으로 구현된 여러 가지 서비스를 이용해야 하는 상황을 생각해보자. 이 때, 스프링 서버에서는 sendMessage API를 이용해 AWS SQS로 Json 형식의 메시지를 전송해야 한다. 반대로 파이썬 코드는 주기적으로 SQS의 큐를 폴링하여, 대기 중인 메시지를 확인하고 처리할 메시지가 있다면 작업을 수행해야 한다.

※ Polling
폴링이란 하나의 장치(또는 프로그램)가 충돌, 회피, 동기화 처리 등을 목적으로 다른 장치(또는 프로그램)의 상태를 주기적으로 검사하여 일정한 조건을 만족할 때, 송수신 등을 처리하는 방식을 의미한다.

이와 같은 분산 시스템의 가장 큰 장점은 소결합된 아키텍처를 구현할 수 있다는 것이다. Server와 Worker 사이에 Queue가 존재하기 때문에 Worker에 장애가 발생하더라도, Server가 메시지 큐에 요청을 저장하는 일은 여전히 정상적으로 수행된다. 이 때, 메시지는 대기열에서 Worker가 정상적으로 재가동되기까지 안전하게 보관된다. 우리는 이를 가리켜 마이크로 서비스 접근 방식이라 부른다.

2. SQS 생성하기

① AWS Management Console의 SQS 메뉴로 들어가 대기열 생성 버튼을 클릭한다.

② 가장 먼저 표준 대기열(Standard)과 순차 대기열(FIFO) 중 하나를 선택해주어야 한다.

  • 표준 대기열: 트랜잭션 처리가 매우 빠르고 AWS SNS와 함께 사용시 메시지 유실 가능성이 매우 낮아진다. 그러나 메시지의 순서를 보장하지 않으며, 동시 요청의 경우 중복 수신 가능성이 존재한다.
  • 순차 대기열: 메시지의 순서를 보장하기 때문에 중복 수신될 가능성이 없다. 다만, 표준 대기열에 비해 트랜잭션 처리가 느리고, 요금이 비싸다.
  • 참고로 프리티어로 사용시, 둘다 무료이니 과금 방지를 위해 표준을 선택할 필요는 없다.
  • 이번 포스팅에선 표준 대기열로 선택하여 진행하였다.

③ 대기열의 이름을 설정한다.

④ 구성 정보를 설정한다.

  • 표시 제한 시간: 큐에 들어있는 메시지를 가져가면 최대 몇초 동안 다른 곳으로 전송될 수 없게 할 것인지에 대한 설정
  • 전송 지연: 큐에 추가된 메시지가 몇초 동안 다른 곳으로 전송되지 못하게 할 것인지에 대한 설정
  • 메시지 수신 대기시간: 폴링이 메시지를 사용할 수 있을 때까지 기다리는 최대 시간, 시간이 짧을 수록 요금이 높음.
  • 메시지 보존 기간: 큐에 들어온 메시지를 며칠동안 보관할 것인지에 대한 설정
  • 최대 메시지 크기: 전송하려는 메시지의 최대 크기를 설정

이 포스팅에서 사용한 구성정보는 아래와 같다. 과금에 대한 정확한 기준은 잘 모르기 때문에, 최대한 보수적으로 구성 정보를 설정하였다.

⑤ 서버측 암호화는 비활성화로 변경한다.

⑥ 나머지는 기본 값을 유지한 채, SQS를 생성하면 된다.

3. AWS SQS로 메시지 보내기

이제 Java Spring으로 SQS에 메시지를 보내보기로 하자.

1) 의존성 추가

먼저 build.gradle에 필요한 의존성을 추가해주자.

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'
implementation 'org.springframework.boot:spring-boot-starter'

2) IAM 권한 추가

① IAM 사용자 탭에 들어간 후 권한 추가 버튼을 클릭한다.

② 직접 정책 연결을 클릭한 후 AmazonSQSFullAccess 권한을 부여한다.

3) 코드 작성

① application.yml

  • 리전과 stack 생성 비활성화를 설정한다.
cloud:
  aws:
    region:
      static: ap-northeast-2
    stack:
      auto: false

② SQSService

  • 코드 작성 시, import문을 잘 확인하기 바란다.
  • QueueMessagingTemplate
    • SQS를 사용하여 메시지를 보내는 데에 사용되는 객체
  • AmazonSQSAsync
    • AWS Java SDK에서 제공하는 SQS의 비동기 클라이언트
    • AmazonSQSAsync 인스턴스를 사용하여 queueMessagingTemplate을 초기화
  • sendMessage
    • 문자열을 인자로 받아 "Hello-There"이라는 이름의 SQS 큐에 해당 메시지를 전송하는 메서드
    • MessageBuilder.withPayload()를 사용하여 메시지를 생성
    • queueMessagingTemplate.send()를 통해 메시지를 전송

③ SQSController

  • 아래와 같이 컨트롤러 코드를 작성한다.

4) 포스트맨 API 테스트

① 포스트맨에서 API를 실행한다.

② SQS 큐로 들어가서 메시지 전송 및 수신 버튼을 클릭한다.

③ 아래와 같이 사용 가능한 메시지가 1개 있음을 확인할 수 있다. 우측의 메시지 폴링 버튼을 클릭해주자.

④ 폴링이 끝나면, 메시지의 간단한 정보를 확인할 수 있다.

⑤ 클릭하여 상세한 정보를 확인할 수도 있다.

4. 파이썬 실행파일과 연동하기

AWS SQS를 파이썬에서 사용하기 위해선, boto3 라이브러리를 설치해주어야한다.

python -m pip install boto3

컨트롤러에서 입력받은 메시지의 내용으로, 이메일을 전송하는 코드를 작성해보기로 하자. 파이썬 실행파일에 대한 자세한 설명은 아래의 링크를 참조하기 바란다.
>> 파이썬 코드로 네이버 이메일 보내기

1) 모듈 import 및 기본 정보 설정


① region_name

  • SQS의 리전을 입력한다.

② aws_access_key

  • 본인의 IAM AccessKey를 입력한다.

③ aws_secret_key

  • 본인의 IAM SecretKey를 입력한다.

④ queue_url

  • SQS 세부정보 탭에서 확인할 수 있다.

2) 메시지 큐에서 메시지 수신하기


① response

  • MaxNumberOfMessages
    • 한 번의 SQS 요청으로 최대 몇 개의 메시지를 받을지 설정
    • 한 번의 SQS 요청에 1개의 메시지만 받는 상태
  • WaitTimeSeconds
    • SQS에서 메시지를 수신하기 위해 대기하는 최대 시간을 지정
    • 새로운 메시지가 없는 경우 최대 10초까지 대기

② messages = response.get('Messages', [])

  • SQS로부터 받아온 응답에서 Messages'라는 키에 해당하는 값을 추출
  • 만약 응답에 'Messages'라는 키가 없으면, 빈 리스트를 할당

③ body

  • 현재 순회하고 있는 메시지의 'Body' 키에 해당하는 값을 추출하여 body 변수에 저장
  • 즉, 해당 메시지의 내용이 담긴 JSON을 body에 저장

④ json.loads(body)

  • body 변수에 들어있는 JSON 문자열을 파싱하여, 딕셔너리 형태로 변환

⑤ text

  • body_dict에서 'message'라는 키에 해당하는 값을 추출하여 text 변수에 저장

⑥ sqs.delete_message

  • 처리가 완료된 메시지를 SQS에서 삭제
  • ReceiptHandle은 삭제의 대상이 되는 메시지를 정확히 지정하기 위해 사용

3) 결과 확인하기

이번에는 message에 "파이썬 프로그램과 연동"이라고 적어 API를 호출해보았다.

그 결과, "파이썬 프로그램과 연동"이라는 내용의 메일이 보내졌다.

참고로, 파이썬 파일은 인텔리제이 안에 같이 있어야 할 필요는 없다. 파이썬 파일은 오직 SQS만 바라보고 있기 때문이다.

코드를 적절히 변경하면 제목과 발신자, 수신자 모두 컨트롤러에게 입력받은 데이터로 변경할 수 있을 것이고, 필요에 따라 request와 json 모듈을 import하여 다른 API를 호출할 수도 있겠다.

이와 같이 AWS SQS 서비스를 잘 활용하면, 백엔드에서도 파이썬의 여러 가지 유용한 기능들을 활용할 수 있게 된다.

[이미지 출처]

profile
Java Spring, Android Kotlin, Node.js, ML/DL 개발을 공부하는 인하대학교 정보통신공학과 학생입니다.

1개의 댓글

comment-user-thumbnail
2023년 8월 2일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기