소프트웨어 아키텍처

동기 vs 비동기 통신

meellon 2026. 7. 2. 05:20

학습 목표

동기 vs 비동기 서비스 간 통신의 결합·지연·일관성 트레이드오프를 설명할 수 있다.

RESTgRPC동기 IPC 관점에서 비교·선택할 수 있다.

메시지 큐·이벤트 기반 비동기 통신의 역할을 설명할 수 있다.

Saga분산 트랜잭션보상(compensating) 으로 다루는 방식을 설명할 수 있다.

문제 상황

  • 주문 API p99 2.8s — Payment·Inventory·Points 순차 REST, hop마다 +400ms
  • Payment 503 → Order 503 — caller가 전체 실패, 재고는 이미 예약됨
  • 모바일이 Catalog 20번 호출 — BFF 없이 chatty REST
  • 팀 A는 JSON REST, 팀 B는 Protobuf gRPC — Gateway에서 변환 지옥
  • "비동기로 바꿨다"는데 consumer 없이 큐만 쌓임 — 멱등·재시도 없음
  • 주문·결제·재고 3서비스 — DB 3개인데 2PC 기대 → 불가

앞서 CAP·일관성을 봤다. 서비스 경계를 넘는 호출 방식일관성·가용성을 결정한다.

1. 동기 vs 비동기

  동기 (request-response) 비동기 (message / event)
호출 응답 올 때까지 대기 보내고 반환 (202·ACK)
결합 시간·가용성 결합 느슨 (broker·큐)
지연 hop 합산 caller 짧음, 처리 백그라운드
일관성 즉시 확인 쉬움 eventual + 보상
장애 callee down → caller 실패 재시도·DLQ·격리

동기가 맞는 때

케이스 이유
즉시 성공/실패 필요 결제 승인, 재고 확정
read-your-writes 방금 쓴 데이터 바로 조회
단순 1~2 hop 오케스트레이션 짧음

비동기가 맞는 때

케이스 이유
부가 side effect 이메일·알림·분석
피크 흡수 큐로 버퍼
다수 consumer fan-out without caller change
  • 하이브리드 — 핵심 path 동기, 나머지 이벤트 (EDA 편과 연결)
  • Network — HTTP 요청-응답 vs keep-alive·지연; 여기서는 아키텍처 선택

2. REST vs gRPC (동기 IPC)

  REST (HTTP/JSON) gRPC (HTTP/2 + Protobuf)
계약 OpenAPI·관례 .proto 강한 스키마
성능 JSON 직렬화·헤더 바이너리·multiplex
스트리밍 SSE·chunk (제한적) 양방향 stream
브라우저 네이티브 gRPC-Web·Gateway 필요
디버깅 curl·브라우저 grpcurl·전용 도구
적합 공개 API·BFF·범용 내부 고QPS·typed RPC

// catalog.proto (conceptual)
service CatalogService {
  rpc GetProduct (GetProductRequest) returns (Product);
  rpc ListProducts (ListRequest) returns (stream Product);
}
GET /products/sku-42 HTTP/1.1
Accept: application/json
  • 외부 REST + 내부 gRPC — 흔한 strangler 패턴
  • 버전 — REST URL·header; gRPC proto package·field number 호환
  • 타임아웃·재시도 — 동기 IPC 필수 (내고장성 편)

3. 메시지 큐·비동기 패턴

메시지 큐 — producer가 메시지를 broker에 넣고, consumer가 비동기로 꺼낸다.

패턴 설명
Point-to-point 큐 하나 ↔ consumer group (work queue)
Pub/Sub topic · 여러 subscriber
Competing consumers 수평 scale-out
DLQ N번 실패 → 격리·수동 조사
보장 의미 설계
At-most-once 유실 가능 로그 드물
At-least-once 중복 가능 멱등 consumer
Exactly-once 구현 비용 Kafka txn·idempotent producer
{
  "messageId": "msg-8f2a",
  "type": "OrderPlaced",
  "orderId": "ord-991",
  "occurredAt": "2026-07-02T06:00:00Z",
  "payload": { "sku": "sku-42", "qty": 2 }
}
  • Correlation ID — 동기 hop + async 한 trace
  • Outbox — DB commit + 같은 TX에 outbox row → relay (데이터 편 예고)
  • RabbitMQ·SQS·Kafka — 순서·지연·보장 다름 → 워크로드 맞춤

4. Saga — 분산 트랜잭션

2PC/XA across services — 느리고 가용성·운영 나쁨. 실무는 Saga.

여러 로컬 TX + 실패 시 보상 TX (rollback 대신 undo)

Choreography (이벤트)

각 서비스가 이벤트 구독 → 다음 이벤트 발행. 중앙 orchestrator 없음.

OrderPlaced → InventoryReserved → PaymentCaptured → OrderConfirmed
              (실패) → InventoryReleased

Orchestration (오케스트레이터)

Saga orchestrator단계 지시·보상 호출.

Orchestrator → reserve inventory → charge payment → confirm order
            ← fail payment ← compensate inventory
  Choreography Orchestration
결합 이벤트 계약 orchestrator API
가시성 흐름 분산 한 곳에서 상태
복잡도 단계 적을 workflow
위험 순환 이벤트 orchestrator SPOF (stateless + durable)
{
  "sagaId": "saga-771",
  "step": "PaymentCapture",
  "compensations": [
    { "service": "inventory", "action": "ReleaseReservation" },
    { "service": "order", "action": "MarkFailed" }
  ]
}
  • Saga = eventual consistency — 각 step 로컬 ACID
  • 멱등 + 보상 가능한 operation 설계 — "취소"가 비즈니스로 정의돼야 함

5. 선택 가이드

질문 방향
사용자가 결과를 기다리나 동기 (또는 폴링·WebSocket)
실패 시 즉시 알려야 하나 동기 + 명확 error
N개 downstream 비동기 fan-out
트랜잭션 여러 DB Saga + 보상
공개 API REST (+ OpenAPI)
내부 고성능 gRPC
hop 3+ 동기 재설계 — BFF·async·saga
안티패턴 대안
Distributed monolith sync mesh 이벤트·API 경계 재정의
무한 retry 동기 timeout·circuit breaker
Chatty REST BFF·batch·gRPC
Saga 없이 다단계 write 보상 설계·outbox

6. 정리

  • 동기 — 즉시·강일관·짧은 chain; 비동기 — decouple·버퍼·eventual
  • REST 공개·범용, gRPC 내부·typed·stream
  • — at-least-once 전제, 멱등·DLQ
  • Saga — 2PC 대신 로컬 TX + 보상
  • 다음 — 내고장성 (timeout·retry·circuit breaker)

다음에 다룰 것

  • 내고장성과 복원력
  • 타임아웃, 재시도, circuit breaker, bulkhead

해당 내용은 Fundamentals of Software Architecture (Mark Richards, Neal Ford) 및 Designing Data-Intensive Applications (Martin Kleppmann) 의 내용을 기반으로 합니다.

'소프트웨어 아키텍처' 카테고리의 다른 글

데이터 저장소 선택  (0) 2026.07.04
내고장성과 복원력  (0) 2026.07.03
CAP과 일관성 모델  (0) 2026.07.01
분산 시스템 기초  (0) 2026.06.30
도메인 주도 설계 입문  (0) 2026.06.29