SW 전공

SW 전공 이론 학습

이론 목록으로 돌아가기

MSA·API와 메시징

모놀리스와 MSA의 차이, REST API 계약·멱등성, API Gateway와 동기·비동기 메시징·Saga를 학습한다.

예상 읽기 8

1. 모놀리스와 MSA

모놀리스

하나의 배포 단위에 여러 업무 기능이 함께 존재한다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Monolith
├─ 회원
├─ 주문
├─ 결제
├─ 배송
└─ 공통 DB

장점:

  • 초기 개발·배포·테스트가 단순할 수 있음
  • 로컬 호출과 단일 트랜잭션 사용 가능
  • 운영 구성요소가 적음

한계:

  • 한 부분 변경도 전체 배포
  • 규모가 커지면 이해·빌드·배포 느려짐
  • 기능별 독립 확장·기술 선택 어려움

MSA

업무 능력 중심의 독립 서비스로 나누고 각각 배포·확장한다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
API Gateway
  ├─ Member Service ─ Member DB
  ├─ Order Service  ─ Order DB
  ├─ Payment Service─ Payment DB
  └─ Delivery Service─ Delivery DB

장점:

  • 서비스별 독립 배포·확장
  • 장애 격리 가능
  • 팀 자율성

비용:

  • 네트워크 실패·지연
  • 분산 데이터 일관성
  • 배포·모니터링·보안 복잡성
  • 계약·버전·테스트 관리

MSA는 서비스 수가 많다는 뜻보다 업무 경계와 독립성의 품질이 중요하다.

2. 서비스 경계

경계는 데이터와 업무 규칙의 응집도를 기준으로 정한다.

좋지 않은 분해:

  • 테이블 하나마다 서비스
  • 기술 계층별 서비스
  • 모든 요청이 여러 서비스에 연쇄 의존
  • 데이터 소유권 불명확

좋은 질문:

  • 독립적으로 변경·배포할 업무 능력인가
  • 데이터와 규칙을 스스로 소유하는가
  • 다른 서비스와 안정된 계약으로 통신하는가
  • 팀이 책임질 수 있는 범위인가

3. REST API 기본

REST는 자원을 URI로 식별하고 HTTP의 표현·메서드·상태코드를 활용하는 아키텍처 스타일이다.

메서드대표 의미멱등성 관점
GET조회멱등
POST생성·명령일반적으로 멱등 보장 안 됨
PUT전체 대체·지정 위치 저장멱등
PATCH부분 변경구현에 따라 다름
DELETE삭제의도상 멱등
HTTP코드 영역 안에서 좌우로 이동할 수 있습니다.
POST /orders
Content-Type: application/json
Idempotency-Key: 5fe0-...

{
  "customerId": "C100",
  "items": [{"productId": "P1", "quantity": 2}]
}

4. API 계약

명확히 할 항목:

  • URI·메서드
  • 요청·응답 스키마
  • 필수·선택 필드
  • 인증·인가
  • 상태코드·오류코드
  • 시간·단위·문자 인코딩
  • 페이징·정렬·필터
  • 타임아웃·재시도
  • 버전·하위호환
  • 속도 제한
JSON코드 영역 안에서 좌우로 이동할 수 있습니다.
{
  "code": "ORDER_NOT_FOUND",
  "message": "주문을 찾을 수 없습니다.",
  "traceId": "T-20260804-001"
}

내부 스택과 SQL을 오류 응답에 노출하지 않는다.

5. 멱등성

같은 요청을 여러 번 수행해도 최종 결과가 한 번 수행한 것과 같게 유지되는 성질이다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
결제 요청 전송
   │ 네트워크 응답 유실
   ▼
클라이언트 재시도
   │
Idempotency-Key로 기존 결과 확인
   ├─ 있으면 기존 결과 반환
   └─ 없으면 한 번 처리 후 결과 저장

멱등성은 중복 메시지·재시도·타임아웃 환경에서 중요하다.

6. API Gateway

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Client
  ↓
API Gateway
├─ 인증·인가
├─ 라우팅
├─ 속도 제한
├─ 요청·응답 변환
├─ 로깅·추적
└─ 서비스 호출

공통 기능을 중앙화할 수 있지만 업무 로직을 과도하게 넣으면 병목과 변경 결합이 생긴다.

7. 동기와 비동기 통신

구분동기 요청·응답비동기 메시징
응답호출 중 기다림나중에 처리
결합시간적으로 강함시간적 결합 감소
오류즉시 반환 가능재시도·DLQ·상태 추적 필요
적용즉시 결과 필요대량·지연 가능·이벤트 처리
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
동기:
A ─요청──► B
A ◄응답── B

비동기:
A ─메시지──► Broker ─► B
A는 바로 다음 작업 가능

비동기라고 데이터가 자동으로 한 번만 처리되는 것은 아니다.

8. 메시지 전달 의미

  • At-most-once: 유실 가능, 중복 없음 지향
  • At-least-once: 재전송으로 유실 감소, 중복 가능
  • Exactly-once: 시스템 전체에서 정확히 한 번의 효과를 보장하기 어려우며 범위와 조건을 확인해야 함

실무에서는 at-least-once 전달과 멱등 소비자를 조합하는 경우가 많다.

9. 이벤트와 명령

  • 명령: 특정 수신자에게 행동 요청
  • 이벤트: 이미 일어난 사실을 알림
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Command: "결제를 처리하라"
Event  : "결제가 완료되었다"

이벤트 이름은 과거형 사실로 표현하면 의미가 명확하다. 소비자가 많아질 때 스키마 변경과 순서를 관리해야 한다.

10. 분산 트랜잭션과 Saga

서비스별 DB를 사용할 때 하나의 로컬 트랜잭션으로 전체 업무를 묶기 어렵다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
주문 생성
   ↓
결제 승인
   ↓
재고 차감
   ↓
배송 요청

중간 실패 시 이미 완료된 작업을 보상해야 한다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
결제 성공
   ↓
재고 차감 실패
   ↓
결제 취소 보상
   ↓
주문 실패 상태

Saga 방식:

  • Choreography: 서비스들이 이벤트를 구독해 다음 작업 수행
  • Orchestration: 중앙 조정자가 단계와 보상 명령 관리

완전한 즉시 일관성보다 최종 일관성을 허용하는지 업무와 사용자 경험을 검토한다.

11. 회복탄력성

  • Timeout
  • 제한된 재시도와 지수 백오프
  • Circuit Breaker
  • Bulkhead
  • Rate Limiting
  • Fallback
  • 메시지 큐와 부하 완충
CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
CLOSED: 정상 호출
   │ 실패 임계치 초과
   ▼
OPEN: 즉시 실패·보호
   │ 대기시간 후
   ▼
HALF-OPEN: 일부 시험 호출
   ├─ 성공 → CLOSED
   └─ 실패 → OPEN

재시도는 일시 오류에는 유용하지만 모든 계층이 동시에 재시도하면 부하 폭증이 발생할 수 있다.

12. 서비스 경계와 데이터 소유

MSA는 테이블을 기술별로 나누는 것이 아니라 업무 능력과 변경 경계를 중심으로 설계한다. 서비스가 서로의 DB를 직접 갱신하면 독립 배포·불변식 소유가 깨진다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
Order Service owns Orders
Payment Service owns Payments
Inventory Service owns Stock
통신: API 또는 event, 직접 테이블 쓰기 금지

13. HTTP 의미와 API 계약

  • GET: 안전하고 원칙적으로 멱등
  • PUT: 대상 자원의 전체 교체 의미, 멱등
  • PATCH: 부분 변경, 구현에 따라 멱등 여부 다름
  • POST: 일반적으로 비멱등이나 idempotency key로 재시도 안전성 보강

상태코드, 오류 형식, pagination, versioning, timeout, rate limit을 계약에 포함한다. 클라이언트가 모르는 필드를 무시할 수 있게 확장 호환성을 설계한다.

14. 메시징의 전달·순서·중복

at-most-once는 손실 가능, at-least-once는 중복 가능, exactly-once는 적용 범위를 확인한다. 동일 partition/key 안에서만 순서를 보장하는 시스템이 많다.

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
consume event → dedup check → local transaction(outbox/inbox)
 → commit → ACK

outbox는 업무 DB 변경과 발행할 이벤트 기록을 같은 로컬 트랜잭션에 넣고 별도 relay가 브로커로 전달한다.

15. Saga 상태 추적

CODE코드 영역 안에서 좌우로 이동할 수 있습니다.
주문 생성 → 결제 승인 → 재고 차감 → 배송 요청
                     실패
결제 취소 ← 주문 취소 ← 재고 차감 실패

보상은 완전한 물리적 rollback이 아닐 수 있다. 외부 송금·이메일처럼 취소 불가능한 부수효과는 상태·재시도·수동 처리 절차를 둔다.

16. 회복탄력성 조합

  • timeout: 대기 상한
  • retry: 일시 실패 재시도, exponential backoff+jitter
  • circuit breaker: 지속 실패 의존성의 호출 차단
  • bulkhead: 자원 풀 격리
  • rate limiter: 유입량 제한

재시도는 상위·하위 계층에서 중첩되면 호출 폭증을 만들 수 있다. 요청 전체 deadline과 retry budget을 공유한다.

확인 문제

  1. PUT과 POST의 일반 멱등성 차이는?
  2. outbox 패턴의 핵심은?
  3. Saga 보상이 물리적 rollback과 다른 이유는?
  4. retry에 jitter를 넣는 이유는?
  5. 서비스가 다른 서비스 DB를 직접 수정하면?