모든 것을 분리하세요. 서비스 간의 가동 시간 기대치가 아닌 이벤트를 통해 통신하도록 하세요.

귀사의 모놀리스(monolith)는 배포 병목 현상이 되고 있습니다. 모든 변경 사항은 팀 간의 조정을 필요로 하며, 청구 버그 하나가 전체 애플리케이션을 다운시킬 수 있습니다. 또는 서로 다른 기능이 다른 속도로 발전하는 새로운 시스템을 구축 중일 수 있습니다. 예를 들어, 주문 관리는 매주 변경되지만 재고 로직은 분기별로 변경됩니다. 연쇄적인 장애를 유발하는 동기식 API 호출 대신 이벤트를 통해 통신하며 독립적으로 개발, 배포 및 확장 가능한 서비스가 필요합니다.
Explore more design patterns and system architectures
MicrocosmWorks는 Apache Kafka 또는 Amazon EventBridge와 같은 내구성 있는 메시지 브로커를 사용하여 이벤트 기반 시스템을 설계합니다. 이 브로커는 컨슈머가 이벤트를 성공적으로 처리할 때까지 이벤트를 보존하여, 중단 중에도 데이터 손실이 없도록 보장합니다. 저희는 장애가 발생한 마이크로서비스가 전체 이벤트 파이프라인을 차단하지 않도록 데드 레터 큐, 지수 백오프 재시도 정책, 그리고 서킷 브레이커를 구현합니다. 다운스트림 서비스가 복구되면, 수동 개입 없이 미처리 이벤트를 자동으로 따라잡습니다.
이벤트 드리븐 통신은 서비스가 즉각적인 응답을 필요로 하지 않을 때, 배포 주기를 분리해야 할 때, 또는 단일 작업이 여러 다운스트림 프로세스를 트리거할 때 더 나은 선택입니다. MicrocosmWorks는 일반적으로 주문 처리, 알림 파이프라인 및 분석 수집에 이벤트 드리븐 패턴을 권장하며, 서브세컨드(sub-second) 응답을 요구하는 사용자 대면 쿼리에는 동기 API를 유지합니다. 우리가 구축하는 많은 프로덕션 시스템은 동기 읽기(synchronous reads)와 비동기 쓰기(asynchronous writes)를 사용하는 하이브리드 접근 방식을 사용합니다.
MicrocosmWorks는 특정 엔티티(예: 특정 주문 또는 사용자)에 대한 모든 이벤트가 동일한 컨슈머 인스턴스에 의해 순차적으로 처리되도록 보장하기 위해 Kafka topics에서 파티션 키 기반 순서화를 사용합니다. 교차 엔티티 순서화가 필요한 시나리오의 경우, 우리는 순서가 맞지 않는 메시지를 안전하게 재처리할 수 있는 멱등성 이벤트 핸들러(idempotent event handlers)를 가진 saga orchestrators를 구현합니다. 또한 컨슈머가 순서 충돌을 감지하고 조정할 수 있도록 이벤트 페이로드(event payloads)에 vector clocks 또는 sequence numbers를 포함시킵니다.
MicrocosmWorks는 Saga pattern을 compensating transactions와 함께 구현합니다. 여기서 각 microservice는 자체 local transaction을 완료한 후 domain events를 발행하며, 다운스트림 서비스는 이에 따라 반응하거나 실패 시 rollback compensations를 트리거합니다. 저희는 이를 outbox pattern과 결합하여, business data와 함께 local outbox table에 이벤트를 원자적으로 작성한 다음, message broker로 안정적으로 발행합니다. 이를 통해 two-phase commits의 성능 및 안정성 저하 없이 eventual consistency를 달성합니다.
MicrocosmWorks는 OpenTelemetry를 사용하여 모든 이벤트를 상관 ID(correlation IDs)와 분산 추적 헤더(distributed tracing headers)로 계측하며, 이를 통해 우리는 Jaeger 또는 Grafana Tempo와 같은 도구에서 모든 참여 마이크로서비스 전반에 걸쳐 비즈니스 트랜잭션(business transaction)의 전체 라이프사이클(lifecycle)을 시각화할 수 있습니다. 또한 우리는 서비스별 처리량(throughput), 컨슈머 지연(consumer lag) 및 처리 지연 시간(processing latency)을 보여주는 실시간 이벤트 흐름 대시보드를 구축하여 병목 현상(bottlenecks)을 쉽게 찾아낼 수 있습니다. 우리의 표준 관측 가능성 스택(observability stack)은 이벤트 메타데이터(event metadata)와 함께 구조화된 로깅(structured logging)을 포함하여, 모든 단일 이벤트를 생산자(producer)부터 모든 컨슈머(consumer)까지 몇 초 안에 추적할 수 있습니다.
이벤트 기반 마이크로서비스는 시스템을 주로 비동기 이벤트를 통해 통신하는 독립적으로 배포 가능한 서비스로 분해합니다. 각 서비스는 자체 데이터를 소유하고, 상태 변경 시 도메인 이벤트를 발행하며, 다른 서비스의 이벤트에 반응합니다. 이는 시간적 결합(temporal coupling)을 제거합니다. 즉, 서비스 A가 작업을 수행하기 위해 서비스 B가 실행될 필요가 없습니다. 이 패턴은 쓰기 및 읽기 모델을 분리하기 위한 CQRS (Command Query Responsibility Segregation), 상태 변경의 전체 이력을 캡처하기 위한 이벤트 소싱, 분산 잠금 없이 다중 서비스 트랜잭션을 관리하기 위한 사가 오케스트레이션(saga orchestration)을 포함합니다.
이 아키텍처는 서비스 간에 도메인 이벤트를 라우팅하는 이벤트 백본 (Kafka, EventBridge, 또는 NATS)을 중심으로 합니다. 각 서비스는 세 가지 경계를 가집니다. 즉, 수신 요청을 처리하고 이벤트를 발행하는 커맨드 핸들러, 읽기 최적화된 프로젝션을 제공하는 쿼리 핸들러, 그리고 다른 서비스의 이벤트에 반응하는 이벤트 프로세서입니다. 사가 오케스트레이터는 이벤트에 귀 기울이고 단계가 실패할 경우 보상 커맨드(compensating commands)를 발행하여 다단계 비즈니스 프로세스(예: 주문 처리)를 조정합니다.
| 레이어 | 기술 |
|---|---|
| 컴퓨트 | Node.js (NestJS), Python (FastAPI), Go — 워크로드 특성에 따라 서비스별 선택 |
| 메시징 | Apache Kafka (MSK), AWS EventBridge, NATS JetStream, RabbitMQ |
| 데이터 | PostgreSQL (트랜잭션), DynamoDB (키-값), Redis (캐싱/잠금), EventStoreDB |
| 오케스트레이션 | Temporal (워크플로우 오케스트레이션), AWS Step Functions, 커스텀 사가 조정자 |
| 관측 가능성 | OpenTelemetry (분산 추적), Datadog, Jaeger, 상관관계 ID(correlation IDs)를 사용한 구조화된 로깅 |
| 사용 시기 | 피해야 할 시기 |
|---|---|
| 여러 팀이 다른 주기로 독립적으로 배포해야 할 때 | 팀 규모가 엔지니어 5명 미만인 경우 — 잘 구조화된 모놀리스가 운영하기 더 간단합니다. |
| 시스템의 여러 부분이 서로 다른 스케일링 특성을 가질 때 | MVP를 구축 중이며 빠르게 출시해야 할 때 — 분산 시스템은 구축 속도가 느립니다. |
| 강력한 감사 추적 및 이벤트 리플레이 기능이 필요할 때 | 모든 작업이 동기적이고 강력하게 일관된 응답을 요구할 때 |
| 도메인에 자연스러운 경계 컨텍스트(주문, 결제, 재고)가 있을 때 | 도메인이 밀접하게 결합되어 있어 — 분할하면 분산된 모놀리스가 될 때 |
MW는 기술 계층(API 서비스, 데이터 서비스, 인증 서비스)별로 마이크로서비스로 분해하지 않습니다. 우리는 DDD (Domain-Driven Design)의 경계 컨텍스트(bounded contexts)를 사용하여 도메인 경계를 따라 분해합니다. 코드를 작성하기 전에, 도메인 이벤트, 커맨드, 애그리게이트(aggregates)를 매핑하기 위한 이벤트 스토밍 워크숍을 진행합니다. 이것이 서비스 경계를 결정하는 요소이며, 기술적 선호도가 아닙니다. 우리는 기업 고객을 위해 모놀리스를 이벤트 기반 아키텍처로 마이그레이션했으며, 가장 일반적인 교훈은 다음과 같습니다. 적고 더 큰 서비스로 시작하고 나중에 분할하며, 그 반대가 되어서는 안 됩니다.
모델은 스스로 작동하지 않습니다. 모델을 훈련하고, 검증하고, 배포하고, 모니터링하는 파이프라인이 실제 제품입니다. 모델은 단지 하나의 아티팩트일 뿐입니다.