메시지 큐 기초 (Message Queue Fundamentals)

메시지 큐 기초 (Message Queue Fundamentals)

난이도: ⭐⭐⭐

개요

메시지 큐는 분산 시스템에서 서비스 간 비동기 통신을 가능하게 하는 핵심 인프라입니다. 이 장에서는 동기와 비동기 통신의 차이, 큐와 토픽의 개념, 메시지 전달 보장 수준, 그리고 멱등성에 대해 학습합니다.


목차

  1. 동기 vs 비동기 통신
  2. 메시지 큐의 이점
  3. 큐 vs 토픽
  4. 메시지 전달 보장
  5. 멱등성 (Idempotency)
  6. 메시지 큐 패턴
  7. 연습 문제

1. 동기 vs 비동기 통신

동기 통신 (Synchronous)

요청 후 응답을 기다리는 방식입니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     동기 통신 (Request-Response)                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐                           ┌──────────┐                   │
│  │ Service A│                           │ Service B│                   │
│  └────┬─────┘                           └────┬─────┘                   │
│       │                                      │                          │
│       │─────── HTTP Request ────────────────►│                          │
│       │                                      │                          │
│       │        (Service A 블로킹)            │ 처리 중...              │
│       │        요청 스레드 대기              │                          │
│       │                                      │                          │
│       │◄────── HTTP Response ───────────────│                          │
│       │                                      │                          │
│       ▼                                      ▼                          │
│  다음 작업 계속                         처리 완료                       │
│                                                                         │
│  특징:                                                                  │
│  - 즉각적인 응답 필요                                                   │
│  - 호출자가 응답 대기                                                   │
│  - Service B 장애 시 Service A도 영향                                   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

비동기 통신 (Asynchronous)

메시지를 보내고 즉시 다른 작업을 계속합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     비동기 통신 (Message Queue)                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐     ┌──────────────┐     ┌──────────┐                   │
│   Service A      Message Queue      Service B                   │
│  (Producer)                        (Consumer)                   │
│  └────┬─────┘     └──────┬───────┘     └────┬─────┘                   │
│                                                                     │
│       │──── Send Msg ───►│                                            │
│       │◄─── ACK ─────────│                                            │
│                                                                     │
│                                                                     │
│  다음 작업 계속          │◄─── Poll ────────│                          │
│  (블로킹 없음)           │──── Deliver ────►│                          │
│                                             처리 중...               │
│                          │◄─── ACK ─────────│                          │
│                                                                      │
│                                       처리 완료                       │
│                                                                         │
│  특징:                                                                  │
│  - 발신자/수신자 독립적                                                 │
│  - 느슨한 결합                                                          │
│  - Service B 장애 시에도 Service A 정상 동작                            │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

통신 방식 비교

특성 동기 비동기
응답 대기 필요 불필요
결합도 강함 느슨함
장애 전파 즉시 전파 격리됨
실시간성 즉시 지연 가능
복잡도 낮음 높음
처리량 제한적 높음

2. 메시지 큐의 이점

디커플링 (Decoupling)

┌─────────────────────────────────────────────────────────────────────────┐
                     강결합 vs 느슨한 결합                               
├─────────────────────────────────────────────────────────────────────────┤
                                                                         
  강결합 (동기):                                                         
  ┌─────┐     ┌─────┐     ┌─────┐     ┌─────┐                          
    A  │────►│  B  │────►│  C  │────►│  D                            
  └─────┘     └─────┘     └─────┘     └─────┘                          
                            X 장애!                                     
                                                                        
  A도 실패! (B 대기  C 장애  전체 실패)                               
                                                                         
├─────────────────────────────────────────────────────────────────────────┤
  느슨한 결합 (비동기):                                                  
                      ┌─────────────┐                                   
                         Message                                      
  ┌─────┐                Queue                ┌─────┐                
    A  │───publish──►├─────────────┤◄──consume──│  B                  
  └─────┘              [msg][msg]             └─────┘                
                      [msg][msg]                X 장애!              
                    └─────────────┘                                    
  A 계속 동작!                                                          
  (메시지는 큐에 보관, B 복구  처리)                                   
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

부하 평준화 (Load Leveling)

┌─────────────────────────────────────────────────────────────────────────┐
│                     부하 평준화                                         │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  Without Queue (직접 호출):                                             │
│                                                                         │
│  요청량    │    ████                                                   │
│           │    ████ ← 피크 시 서버 과부하!                             │
│  처리용량 │ ───████─────────────                                       │
│           │    ████                                                    │
│           └────────────────────────► 시간                              │
│                                                                         │
├─────────────────────────────────────────────────────────────────────────┤
│  With Queue (버퍼링):                                                   │
│                                                                         │
│  요청량    │    ████                                                   │
│           │    ████                                                    │
│  큐 크기  │ ───████████████──                                          │
│           │    ████████████                                            │
│  처리량   │ ═══════════════════════ ← 일정한 처리                      │
│           └────────────────────────► 시간                              │
│                                                                         │
│  큐가 버퍼 역할을 하여:                                                 │
│  - 피크 트래픽을 흡수                                                   │
│  - Consumer는 일정한 속도로 처리                                        │
│  - 시스템 안정성 향상                                                   │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

확장성 (Scalability)

┌─────────────────────────────────────────────────────────────────────────┐
                     수평 확장                                           
├─────────────────────────────────────────────────────────────────────────┤
                                                                         
              ┌────────────┐                                            
                Message                                               
                 Queue                                                
              ├────────────┤                                            
  Producer───►│ [m1][m2]                                               
               [m3][m4]                                               
               [m5][m6]                                               
              └─────┬──────┘                                            
                                                                        
         ┌──────────┼──────────┐                                        
                                                                     
    ┌─────────┐ ┌─────────┐ ┌─────────┐                                
    Consumer1 Consumer2 Consumer3                                
      (m1)      (m2)      (m3)                                   
    └─────────┘ └─────────┘ └─────────┘                                
                                                                         
  처리량 증가 :                                                        
  - Consumer만 추가하면                                                
  - Producer 코드 변경 불필요                                            
  - 메시지는 Consumer들에게 자동 분배                                    
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

내구성 (Durability)

┌─────────────────────────────────────────────────────────────────────────┐
                     메시지 영속성                                       
├─────────────────────────────────────────────────────────────────────────┤
                                                                         
  ┌──────────┐     ┌──────────────────────────┐                        
   Producer │────►│ Message Queue (Durable)                          
  └──────────┘     ├──────────────────────────┤                        
                     메모리                                           
                     ┌──────────────────┐                            
                      [msg1] [msg2]                                
                     └────────┬─────────┘                            
                                                                    
                                                                    
                     디스크 (WAL)                                    
                     ┌──────────────────┐                            
                      msg1, msg2, ...                              
                     └──────────────────┘                            
                   └──────────────────────────┘                        
                                                                         
  장애 복구:                                                             
  1. 브로커 재시작                                                       
  2. 디스크에서 메시지 복원                                              
  3. Consumer에게 재전송                                                 
   메시지 유실 방지                                                     
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

3. 큐 vs 토픽

Point-to-Point (Queue)

하나의 메시지는 하나의 Consumer만 처리합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Point-to-Point (Queue)                              │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                         ┌───────────────────┐                          │
│  ┌──────────┐          │      Queue        │                          │
│  │Producer 1│─────────►│ ┌───┬───┬───┬───┐ │                          │
│  └──────────┘          │ │ A │ B │ C │ D │ │                          │
│                        │ └───┴───┴───┴───┘ │                          │
│  ┌──────────┐          │                   │          ┌──────────┐    │
│  │Producer 2│─────────►│ 각 메시지는       │─────────►│Consumer 1│    │
│  └──────────┘          │ 하나의 Consumer만 │   A,C    └──────────┘    │
│                        │ 처리              │                          │
│                        │                   │          ┌──────────┐    │
│                        │                   │─────────►│Consumer 2│    │
│                        │                   │   B,D    └──────────┘    │
│                        └───────────────────┘                          │
│                                                                         │
│  사용 사례:                                                             │
│  - 작업 분배 (Work Queue)                                               │
│  - 주문 처리                                                            │
│  - 이메일 발송 큐                                                       │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Publish/Subscribe (Topic)

하나의 메시지가 모든 Subscriber에게 전달됩니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Publish/Subscribe (Topic)                           │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                         ┌───────────────────┐                          │
│  ┌──────────┐          │      Topic        │         ┌────────────┐   │
│  │Publisher │─────────►│ ┌───┬───┬───┬───┐ │────────►│Subscriber 1│   │
│  └──────────┘          │ │ A │ B │ C │ D │ │  A,B,   │ (모든 메시지)  │
│                        │ └───┴───┴───┴───┘ │  C,D    └────────────┘   │
│                        │                   │                          │
│                        │ 모든 Subscriber가 │         ┌────────────┐   │
│                        │ 모든 메시지를     │────────►│Subscriber 2│   │
│                        │ 받음              │  A,B,   │ (모든 메시지)  │
│                        │                   │  C,D    └────────────┘   │
│                        │                   │                          │
│                        │                   │         ┌────────────┐   │
│                        │                   │────────►│Subscriber 3│   │
│                        │                   │  A,B,   │ (모든 메시지)  │
│                        └───────────────────┘  C,D    └────────────┘   │
│                                                                         │
│  사용 사례:                                                             │
│  - 이벤트 브로드캐스트                                                  │
│  - 로그 수집 (여러 시스템이 같은 로그 수신)                             │
│  - 가격 업데이트 (모든 클라이언트에게 전파)                             │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Consumer Group (하이브리드)

Kafka 스타일: Topic + 그룹 내 분산 처리

┌─────────────────────────────────────────────────────────────────────────┐
│                     Consumer Group                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                         ┌───────────────────┐                          │
│                        │      Topic        │                          │
│  ┌──────────┐          │ ┌───┬───┬───┬───┐ │                          │
│  │Publisher │─────────►│ │ A │ B │ C │ D │ │                          │
│  └──────────┘          │ └───┴───┴───┴───┘ │                          │
│                        └─────────┬─────────┘                          │
│                                  │                                     │
│              ┌───────────────────┼───────────────────┐                 │
│              ▼                   ▼                   ▼                 │
│  ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐    │
│  │  Consumer Group 1 │ │  Consumer Group 2 │ │  Consumer Group 3 │    │
│  │ (Order Service)   │ │ (Analytics)       │ │ (Notification)    │    │
│  ├───────────────────┤ ├───────────────────┤ ├───────────────────┤    │
│  │ ┌────┐ ┌────┐    │ │ ┌────┐ ┌────┐    │ │ ┌────┐            │    │
│  │ │C1-1│ │C1-2│    │ │ │C2-1│ │C2-2│    │ │ │C3-1│            │    │
│  │ │A,C │ │B,D │    │ │ │A,C │ │B,D │    │ │ │A,B,C,D│         │    │
│  │ └────┘ └────┘    │ │ └────┘ └────┘    │ │ └────┘            │    │
│  └───────────────────┘ └───────────────────┘ └───────────────────┘    │
│                                                                         │
│  동작:                                                                  │
│  - 각 그룹은 모든 메시지 수신 (Pub/Sub)                                 │
│  - 그룹 내에서는 메시지 분산 (Point-to-Point)                           │
│  - 확장: 그룹 내 Consumer 추가                                          │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

패턴 비교

특성 Queue (P2P) Topic (Pub/Sub) Consumer Group
메시지 복사 1:1 1:N 그룹당 1
부하 분산 O X 그룹 내 O
브로드캐스트 X O 그룹간 O
확장성 Consumer 추가 제한적 유연함

4. 메시지 전달 보장

At-Most-Once (최대 한 번)

메시지가 유실될 수 있지만, 중복은 없습니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     At-Most-Once                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐     ┌─────────┐     ┌──────────┐                        │
│   Producer        Queue        Consumer                         │
│  └────┬─────┘     └────┬────┘     └────┬─────┘                        │
│                                                                     │
│       │── Send(msg) ──►│                                              │
│                       │── Deliver ───►│                               │
│                                      X 처리  장애!                 │
│                                                                     │
│                        (메시지 삭제)                                │
│                                                                     │
│                        재전송 없음                                  │
│                                                                     │
│                                                                         │
│  구현: ACK 전에 메시지 삭제                                             │
│                                                                         │
│  장점:                                                                  │
│  - 중복 처리 불필요                                                     │
│  - 가장 빠른 성능                                                       │
│                                                                         │
│  단점:                                                                  │
│  - 메시지 유실 가능                                                     │
│                                                                         │
│  사용 사례:                                                             │
│  - 실시간 센서 데이터 (일부 유실 허용)                                  │
│  - 로그 수집 (완전성보다 성능 중요)                                     │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

At-Least-Once (최소 한 번)

메시지가 중복될 수 있지만, 유실은 없습니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     At-Least-Once                                       │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐     ┌─────────┐     ┌──────────┐                        │
│   Producer        Queue        Consumer                         │
│  └────┬─────┘     └────┬────┘     └────┬─────┘                        │
│                                                                     │
│       │── Send(msg) ──►│                                              │
│                       │── Deliver ───►│                               │
│                                       처리 완료                     │
│                                      X ACK  장애!                  │
│                                                                     │
│                        (ACK 미수신)                                 │
│                                                                     │
│                       │── Redeliver ─►│  재전송 (중복!)             │
│                       │◄── ACK ───────│                               │
│                                                                     │
│                                                                         │
│  구현: ACK 후에만 메시지 삭제                                           │
│                                                                         │
│  장점:                                                                  │
│  - 메시지 유실 없음                                                     │
│                                                                         │
│  단점:                                                                  │
│  - 중복 처리 필요 (멱등성 필요)                                         │
│                                                                         │
│  사용 사례:                                                             │
│  - 결제 처리 (유실 불가, 멱등성 구현)                                   │
│  - 주문 처리                                                            │
│  - 이메일 발송                                                          │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Exactly-Once (정확히 한 번)

이론적으로 가장 이상적이지만, 구현이 복잡합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Exactly-Once                                        │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  순수한 Exactly-Once는 분산 시스템에서 불가능!                          │
│  (Two Generals Problem)                                                │
│                                                                         │
│  실용적 구현: "Effectively Once"                                        │
│                                                                         │
│  방법 1: At-Least-Once + 멱등성 Consumer                                │
│  ┌──────────┐     ┌─────────┐     ┌──────────────────┐                │
│  │ Producer │────►│  Queue  │────►│ Idempotent       │                │
│  └──────────┘     └─────────┘     │ Consumer         │                │
│                                   │ ┌──────────────┐ │                │
│                                   │ │Processed IDs │ │                │
│                                   │ │{id1, id2, ..}│ │                │
│                                   │ └──────────────┘ │                │
│                                   │ 이미 처리된 건   │                │
│                                   │ 무시             │                │
│                                   └──────────────────┘                │
│                                                                         │
│  방법 2: 트랜잭션 기반 (Kafka Transactions)                             │
│  ┌──────────────────────────────────────────────────────────┐          │
│  │  Transaction                                             │          │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐      │          │
│  │  │ Read from   │──│ Process     │──│ Write to    │      │          │
│  │  │ input topic │  │             │  │ output topic│      │          │
│  │  └─────────────┘  └─────────────┘  └─────────────┘      │          │
│  │                                                          │          │
│  │  → 모두 성공 또는 모두 실패                              │          │
│  └──────────────────────────────────────────────────────────┘          │
│                                                                         │
│  사용 사례:                                                             │
│  - 금융 거래                                                            │
│  - 재고 관리                                                            │
│  - 스트림 처리 (Kafka Streams)                                          │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

전달 보장 비교

보장 수준 유실 중복 성능 복잡도
At-Most-Once 가능 없음 최고 낮음
At-Least-Once 없음 가능 좋음 중간
Exactly-Once 없음 없음 낮음 높음

5. 멱등성 (Idempotency)

멱등성이란?

같은 연산을 여러 번 수행해도 결과가 동일한 성질입니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     멱등성 (Idempotency)                                │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  멱등 연산:                                                             │
│  f(f(x)) = f(x)                                                        │
│                                                                         │
│  예시:                                                                  │
│  ┌────────────────────────────────────────────────────────────────┐    │
│  │  연산                     │ 멱등?  │ 설명                      │    │
│  ├────────────────────────────────────────────────────────────────┤    │
│  │  x = 5                    │  O     │ 여러 번 해도 x=5         │    │
│  │  DELETE /users/123        │  O     │ 이미 삭제된 것 다시 삭제 │    │
│  │  PUT /users/123 {name:A}  │  O     │ 같은 값으로 덮어쓰기     │    │
│  ├────────────────────────────────────────────────────────────────┤    │
│  │  x = x + 1                │  X     │ 할 때마다 증가           │    │
│  │  POST /orders             │  X     │ 호출마다 새 주문 생성    │    │
│  │  account.balance -= 100   │  X     │ 호출마다 차감            │    │
│  └────────────────────────────────────────────────────────────────┘    │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

멱등성 구현 패턴

┌─────────────────────────────────────────────────────────────────────────┐
                     멱등성 구현 방법                                    
├─────────────────────────────────────────────────────────────────────────┤
                                                                         
  방법 1: Idempotency Key                                               
                                                                         
  ┌──────────┐                         ┌────────────────────────┐       
    Client                                   Server                 
  └────┬─────┘                           ┌──────────────────┐         
                                         Processed Keys            
       │──POST /payment                   {key1, key2, ...}         
         Idempotency-Key: abc123       └──────────────────┘         
         {amount: 100}                                              
                                        1. Check: abc123?           
                                        2. Not found  처리          
                                        3. Store abc123             
       │◄─ 200 OK ─────────────────────│                               
                                                                     
       │──POST /payment (재시도)                                      
         Idempotency-Key: abc123                                    
         {amount: 100}                                              
                                        1. Check: abc123?           
                                        2. Found  기존 응답         
       │◄─ 200 OK (동일 응답) ─────────│                               
                                                                     
                                                                         
├─────────────────────────────────────────────────────────────────────────┤
  방법 2: 버전/조건부 업데이트                                           
                                                                         
  -- 비멱등적 UPDATE                                                     
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;             
  -- 실행할 때마다 100 감소                                              
                                                                         
  -- 멱등적 UPDATE (버전 사용)                                           
  UPDATE accounts                                                        
  SET balance = balance - 100, version = 2                               
  WHERE id = 1 AND version = 1;                                         
  -- version이 1일 때만 실행 ( 번만 성공)                              
                                                                         
├─────────────────────────────────────────────────────────────────────────┤
  방법 3: 절대값 설정                                                    
                                                                         
  -- 비멱등적                                                            
  INSERT INTO orders (user_id, amount) VALUES (1, 100);                 
                                                                         
  -- 멱등적 (UPSERT)                                                     
  INSERT INTO orders (order_id, user_id, amount)                        
  VALUES ('order-abc123', 1, 100)                                       
  ON CONFLICT (order_id) DO NOTHING;                                    
                                                                         
└─────────────────────────────────────────────────────────────────────────┘

멱등성 Consumer 구현 예시

class IdempotentConsumer:
    def __init__(self, redis_client, db):
        self.redis = redis_client
        self.db = db

    def process_message(self, message):
        message_id = message['id']

        # 1. 이미 처리된 메시지인지 확인
        if self.is_processed(message_id):
            print(f"Message {message_id} already processed, skipping")
            return

        # 2. 비즈니스 로직 처리
        try:
            self.handle_business_logic(message)

            # 3. 처리 완료 표시 (원자적으로)
            self.mark_processed(message_id)

        except Exception as e:
            # 처리 실패 시 재시도 가능
            raise

    def is_processed(self, message_id):
        # Redis SET 사용 (TTL 설정으로 메모리 관리)
        return self.redis.sismember("processed_messages", message_id)

    def mark_processed(self, message_id):
        # 24시간 후 자동 삭제
        self.redis.sadd("processed_messages", message_id)
        self.redis.expire("processed_messages", 86400)

    def handle_business_logic(self, message):
        # 실제 비즈니스 로직
        if message['type'] == 'payment':
            self.process_payment(message['data'])

6. 메시지 큐 패턴

Work Queue (Task Queue)

작업을 여러 워커에게 분배합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Work Queue Pattern                                  │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                       ┌─────────────────┐                              │
│                       │   Work Queue    │                              │
│  ┌──────────┐        │ ┌───┬───┬───┐   │         ┌──────────┐         │
│  │ Producer │───────►│ │T1 │T2 │T3 │   │────────►│ Worker 1 │         │
│  │  (Web)   │        │ ├───┼───┼───┤   │         └──────────┘         │
│  └──────────┘        │ │T4 │T5 │T6 │   │                              │
│                       │ └───┴───┴───┘   │         ┌──────────┐         │
│                       └─────────────────┘────────►│ Worker 2 │         │
│                                                   └──────────┘         │
│  사용 사례:                                        ┌──────────┐         │
│  - 이미지 리사이징                          ─────►│ Worker 3 │         │
│  - PDF 생성                                        └──────────┘         │
│  - 이메일 발송                                                          │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Request-Reply

비동기 요청-응답 패턴입니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Request-Reply Pattern                               │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐     ┌─────────────┐     ┌──────────┐                    │
│  │ Requester│     │Request Queue│     │ Replier  │                    │
│  │          │     └─────────────┘     │          │                    │
│  │          │     ┌─────────────┐     │          │                    │
│  │          │     │Reply Queue  │     │          │                    │
│  └────┬─────┘     └──────┬──────┘     └────┬─────┘                    │
│       │                  │                 │                           │
│       │─Request(replyTo:Q1,correlationId:C1)─►│                        │
│       │                  │                 │                           │
│       │                  │                 │ 처리                      │
│       │                  │                 │                           │
│       │◄──Reply(correlationId:C1)──────────│                           │
│       │                  │                 │                           │
│                                                                         │
│  메시지 구조:                                                           │
│  Request: {                                                             │
│    correlationId: "req-123",                                           │
│    replyTo: "reply-queue-A",                                           │
│    body: { ... }                                                       │
│  }                                                                      │
│                                                                         │
│  Reply: {                                                               │
│    correlationId: "req-123",  // 요청과 응답 매칭                       │
│    body: { ... }                                                       │
│  }                                                                      │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Dead Letter Queue (DLQ)

처리 실패한 메시지를 보관합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Dead Letter Queue                                   │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│                       ┌─────────────────┐                              │
│  ┌──────────┐        │   Main Queue    │         ┌──────────┐         │
│  │ Producer │───────►│ ┌───┬───┬───┐   │────────►│ Consumer │         │
│  └──────────┘        │ │ A │ B │ C │   │         └────┬─────┘         │
│                       │ └───┴───┴───┘   │              │                │
│                       └────────┬────────┘              │                │
│                                │                       │                │
│                                │ 처리 실패             │                │
│                                │ (재시도 초과)         │                │
│                                ▼                       ▼                │
│                       ┌─────────────────┐        실패! (B 메시지)      │
│                       │ Dead Letter Q   │              │                │
│                       │ ┌───┐           │◄─────────────┘                │
│                       │ │ B │           │                               │
│                       │ └───┘           │                               │
│                       └────────┬────────┘                               │
│                                │                                        │
│                                ▼                                        │
│                       수동 검토 / 재처리                                │
│                                                                         │
│  DLQ 활용:                                                              │
│  - 실패 원인 분석                                                       │
│  - 수동 재처리                                                          │
│  - 알림/모니터링                                                        │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

Priority Queue

우선순위에 따라 메시지를 처리합니다.

┌─────────────────────────────────────────────────────────────────────────┐
│                     Priority Queue                                      │
├─────────────────────────────────────────────────────────────────────────┤
│                                                                         │
│  ┌──────────┐     ┌─────────────────────┐     ┌──────────┐            │
│  │ Producer │     │   Priority Queue    │     │ Consumer │            │
│  └────┬─────┘     │                     │     └────┬─────┘            │
│       │           │ High   ┌───┬───┐    │          │                  │
│       │──(P:High)─│───────►│ A │ D │    │──────────│                  │
│       │           │        └───┴───┘    │          │                  │
│       │──(P:Med)──│ Medium ┌───┬───┐    │          │                  │
│       │           │───────►│ B │   │    │          │                  │
│       │           │        └───┴───┘    │          │                  │
│       │──(P:Low)──│ Low    ┌───┬───┐    │          │                  │
│       │           │───────►│ C │ E │    │          │                  │
│       │           │        └───┴───┘    │          │                  │
│       │           └─────────────────────┘          │                  │
│       │                                            │                  │
│       │           처리 순서: A → D → B → C → E     │                  │
│                                                                         │
│  구현 방법:                                                             │
│  1. 우선순위별 별도 큐 + 가중치 폴링                                    │
│  2. 단일 큐 + 힙 정렬                                                   │
│  3. RabbitMQ: x-max-priority 설정                                      │
│                                                                         │
└─────────────────────────────────────────────────────────────────────────┘

7. 연습 문제

연습 1: 통신 방식 선택

다음 시나리오에서 동기/비동기 중 적절한 방식을 선택하세요:

  1. 사용자 로그인 인증
  2. 주문 후 확인 이메일 발송
  3. 결제 승인 요청
  4. 로그 수집
  5. 실시간 채팅 메시지

연습 2: 전달 보장 선택

다음 사용 사례에 적합한 전달 보장 수준을 선택하세요:

  1. IoT 센서 온도 데이터
  2. 은행 송금 요청
  3. 뉴스 피드 업데이트
  4. 주문 생성 이벤트
  5. 게임 플레이어 위치 업데이트

연습 3: 멱등성 설계

다음 연산을 멱등하게 만드는 방법을 설계하세요:

  1. 계좌에서 100원 출금
  2. 상품 재고 1개 감소
  3. 이메일 발송
  4. 포인트 적립

다음 단계

12_Message_System_Comparison.md에서 Kafka, RabbitMQ, AWS SQS/SNS 등 주요 메시지 시스템을 비교해봅시다!


참고 자료

  • "Enterprise Integration Patterns" - Gregor Hohpe, Bobby Woolf
  • RabbitMQ Official Documentation
  • Apache Kafka Documentation
  • AWS Messaging Services
  • "Designing Data-Intensive Applications" - Martin Kleppmann
to navigate between lessons