Backend Web/AWS · Cloud

[AWS] AWS SQS

sofiaaa 2025. 5. 20. 13:19
반응형

조만간 AWS 카테고리를 하나 만들어야겠다.

AWS 를 도입하게 되어 이것 저것 설정이나 하나씩 확인 중인데 정리가 필요해 보인다.

SQS 도 아직 사용은 안 하는 것으로 보이나 설정은 추가되어 있다.

회사에서 사용할 일이 없을 건 알지만 추후에 내가 사용하게 될 수도 있으니까 ~

 

✅ 1. AWS SQS란?

AWS에서 제공하는 완전관리형 메시지 큐 서비스

  • 생산자(Producer)가 메시지를 큐에 넣고
  • 소비자(Consumer) 가 비동기로 가져와 처리
  • 시스템 간 비동기 처리, 트래픽 분산, 내결함성 확보에 유용

 

📦 주요 특징


표준 큐 무제한 처리량, 순서 보장 안 됨, 최소 1회 전송 보장
FIFO 큐 순서 보장, 중복 제거, 처리량 제한 (300 TPS 기본)
메시지 보존 기간 1분 ~ 14일
가시성 타임아웃 소비 후 일정 시간 안에 다시 안 보이도록 설정 가능
 

✅ 2. Spring Boot에서 AWS SQS 적용 방법

① 의존성 추가 (Gradle 기준)

implementation 'software.amazon.awssdk:sqs'

AWS SDK v2 사용 권장 (v1은 더 이상 최신 아님)


② AWS 자격증명 설정

  • ~/.aws/credentials 또는
  • application.yml에 명시 or EC2/ECS 환경 변수 사용
cloud: aws: credentials: access-key: YOUR_KEY secret-key: YOUR_SECRET region: static: ap-northeast-2

✅ 3. 예제 코드

① 메시지 보내기 (Producer) 

import software.amazon.awssdk.services.sqs.SqsClient; 
import software.amazon.awssdk.services.sqs.model.*; 
@Service 
public class SqsSender { 
	private final SqsClient sqsClient; 
    private final String queueUrl = "https://sqs.ap-northeast-2.amazonaws.com/123456789012/your-queue"; 
    public SqsSender(SqsClient sqsClient) { 
    	this.sqsClient = sqsClient; 
    } 
    public void sendMessage(String message) { 
    	SendMessageRequest sendMsgRequest = SendMessageRequest.builder() 
        .queueUrl(queueUrl) .messageBody(message) .build(); 
        sqsClient.sendMessage(sendMsgRequest); 
    } 
}
 

② 메시지 받기 (Consumer)

 
@Service 
public class SqsReceiver { 
    private final SqsClient sqsClient; 
    private final String queueUrl = "https://sqs.ap-northeast-2.amazonaws.com/123456789012/your-queue"; 
    public SqsReceiver(SqsClient sqsClient) { 
        this.sqsClient = sqsClient; 
    } 
    @Scheduled(fixedDelay = 5000) 
    public void pollMessages() { 
    	ReceiveMessageRequest receiveRequest = ReceiveMessageRequest.builder() 
        .queueUrl(queueUrl) .maxNumberOfMessages(5) .waitTimeSeconds(10) .build(); 
        List<Message> messages = sqsClient.receiveMessage(receiveRequest).messages(); 
        for (Message msg : messages) { 
        	System.out.println("Received: " + msg.body()); // 처리 후 삭제 
            sqsClient.deleteMessage(DeleteMessageRequest.builder() .queueUrl(queueUrl)
            .receiptHandle(msg.receiptHandle()) .build()); 
        } 
    } 
}

✅ 4. 주의할 점


중복 메시지 최소 1회 전송 보장, 중복 발생 가능 → 중복처리 필요
메시지 삭제 직접 deleteMessage 호출 안 하면 큐에 남아 있음
가시성 타임아웃 너무 짧게 설정 시, 처리가 끝나기 전에 다시 보일 수 있음
최대 메시지 크기 256KB (더 크면 S3와 연동 필요)
 

✅ SQS 언제 쓰냐?

  • 마이크로서비스 간 비동기 통신
  • 트래픽 급증 시 처리 분산 (버퍼 역할)
  • 사용자 행동 로그 적재
  • 이벤트 기반 처리

✅ 참고 툴

  • AWS 콘솔에서 큐 생성
  • LocalStack 으로 로컬 테스트 가능

✅ Dead Letter Queue(DLQ)란?

메시지를 여러 번 처리 시도했는데도 실패하면 자동으로 별도의 큐(DLQ)에 격리시키는 기능입니다.

  • 무한 재시도 방지
  • 문제 메시지를 따로 조사/알림 처리 가능
  • 시스템 장애를 확산시키지 않음

✅ SQS DLQ 설정 방식 (요약)

  1. 일반 큐 (Main Queue) 하나 생성
  2. DLQ 역할의 큐 하나 더 생성
  3. Main Queue 설정에서:
    • Redrive policy → DLQ 설정
    • Maximum Receives 설정 (예: 3번 실패하면 DLQ로 이동)

✅ Spring에서 DLQ 처리 흐름

예시 상황:

  • Main Queue: my-queue
  • DLQ: my-queue-dlq
  • MaximumReceiveCount: 3

메시지가 3번 처리 실패하면 DLQ로 자동 이동됨.


✅ DLQ 메시지 확인/처리 방법

1. DLQ에서 메시지 읽기 (예: @Scheduled 로 polling)

@Scheduled(fixedDelay = 10000) 
public void processDLQ() { 
	ReceiveMessageRequest receiveRequest = ReceiveMessageRequest.builder() 
    .queueUrl(dlqUrl) .maxNumberOfMessages(5) .waitTimeSeconds(10) .build(); 
    List<Message> messages = sqsClient.receiveMessage(receiveRequest).messages(); 
    for (Message msg : messages) { 
    	log.warn("DLQ 메시지: {}", msg.body()); // ✅ 필요한 경우: 저장, 알림, 재시도 처리 등 
        // sqsClient.sendMessage(...)로 다시 Main Queue로 복구 시도도 가능 
        sqsClient.deleteMessage(DeleteMessageRequest.builder() .queueUrl(dlqUrl) .
     	receiptHandle(msg.receiptHandle()) .build()); 
    } 
}

✅ DLQ를 어떻게 활용하나?


🛠 문제 진단 잘못된 데이터 메시지 로그 분석
📢 알림 DLQ에 메시지가 생기면 알람 (ex. CloudWatch Alarm, SNS 등)
🔁 재처리 수동 또는 자동으로 다시 Main Queue로 복구 처리 가능
📂 저장 데이터베이스나 S3로 백업 가능
 

✅ 참고: DLQ 설정 화면 (콘솔 기준)

  1. AWS SQS 콘솔 → Main Queue 선택
  2. Redrive policy → "DLQ 사용" 선택
  3. DLQ로 사용할 Queue 선택
  4. 최대 수신 횟수 (maxReceiveCount) 지정 (예: 3)

🔄 다시 Main Queue로 복구하는 방법

sqsClient.sendMessage(SendMessageRequest.builder() .queueUrl(mainQueueUrl) 
.messageBody(msg.body()) .build());

✅ 결론

  • DLQ는 실패한 메시지를 격리하여 시스템 안정성을 지켜주는 핵심 기능
  • Spring에서는 스케줄러 기반 처리, 로그 저장, 재전송 등의 방식으로 활용
  • 운영 중에는 CloudWatch 알람과 연동해서 자동 감지 시스템 구축도 추천
반응형

'Backend Web > AWS · Cloud' 카테고리의 다른 글

[AWS] 클라우드 서비스 유형  (0) 2022.04.04