125 lines
9.7 KiB
Markdown
125 lines
9.7 KiB
Markdown
---
|
|
title: Event Sourcing as an Alternative to Outbox (microservices.io)
|
|
source_type: official-doc
|
|
url: https://microservices.io/patterns/data/event-sourcing.html
|
|
archive_url:
|
|
status: raw
|
|
confidence: high
|
|
tags: [ca-outbox-pattern, event-sourcing, alternative, microservices-io, official-doc]
|
|
related_branches: [feature-domain-event-outbox-contract, feature-background-job-async-contract]
|
|
related_projects: [ca-skeleton-operational-contract]
|
|
created: 2026-05-22
|
|
last_reviewed: 2026-05-27
|
|
---
|
|
|
|
# Event Sourcing as an Alternative to Outbox (microservices.io)
|
|
|
|
> Layer: `raw/official-docs/` — microservices.io 의 "Pattern: Event sourcing" 문서. ca-tmpl outbox 대안 중 **대안 4 (event sourcing — 도메인 모델 자체 교체)** 의 1차 근거.
|
|
|
|
## Parent / 활용 branch (필수)
|
|
|
|
| Branch | 이 자료가 정당화하는 결정 |
|
|
|---|---|
|
|
| [[raw/branch-notes/feature-domain-event-outbox-contract]] | outbox 6대안 비교에서 "event sourcing" 위치 — outbox 자체가 불요해지는 모델로 분류하는 근거 |
|
|
| [[raw/branch-notes/feature-background-job-async-contract]] | event 발행을 background job 으로 처리할지 vs event store 내장 subscriber 로 처리할지의 분기 근거 |
|
|
|
|
특정 branch 없이 foundational 조사로 수집한 경우:
|
|
|
|
- [[raw/project-notes/ca-skeleton-operational-contract]] — Contract #19 (Domain Application Readiness Contract) 의 Domain Event / Outbox 항목에서 event sourcing 채택 안 함의 근거 자료
|
|
|
|
## 컨텍스트
|
|
|
|
ca-tmpl 의 SKIP LOCKED outbox 결정에 대한 **대안 4: event sourcing**. outbox 자체가 불요해지는 모델 — event store 가 source of truth 가 되므로 별도 발행 메커니즘이 필요 없거나 매우 단순해짐.
|
|
|
|
## 출처 / Source
|
|
|
|
- 원본 URL: https://microservices.io/patterns/data/event-sourcing.html
|
|
- 아카이브 URL: (미수집)
|
|
- 저자 / 조직: Chris Richardson (microservices.io)
|
|
- 발행일: rolling (microservices.io patterns catalog)
|
|
- 마지막 확인일: 2026-05-27
|
|
- 보조 자료: Confluent blog "Event Sourcing, CQRS, and Stream Processing" (`https://www.confluent.io/blog/event-sourcing-cqrs-stream-processing-apache-kafka-whats-connection/`)
|
|
|
|
## 핵심 인용 / Key quotes (verbatim)
|
|
|
|
> [§Solution] "Event sourcing persists the state of a business entity such an Order or a Customer as a sequence of state-changing events."
|
|
|
|
> [§Solution] "Whenever the state of a business entity changes, a new event is appended to the list of events."
|
|
|
|
> [§Solution] "Since saving an event is a single operation, it is inherently atomic."
|
|
|
|
> [§Solution] "The application reconstructs an entity's current state by replaying the events."
|
|
|
|
> [§Solution] "When a service saves an event in the event store, it is delivered to all interested subscribers."
|
|
|
|
> [§Resulting Context — Benefits] "It solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes."
|
|
|
|
> [§Resulting Context — Drawbacks] "The event store is difficult to query since it requires typical queries to reconstruct the state of the business entities."
|
|
|
|
보조 인용 (Confluent blog, 동일 주제):
|
|
|
|
> [Confluent — Event Sourcing, CQRS, and Stream Processing] "Event sourcing involves modeling the state changes made by applications as an immutable sequence or 'log' of events."
|
|
|
|
## Claims Extracted / 추출된 주장
|
|
|
|
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|
|
|---|---|---|---|---|---|
|
|
| ES-OUTBOX-C1 | Event sourcing 은 business entity 의 state 를 일련의 state-changing events 의 sequence 로 영속화한다 | [§Solution] "Event sourcing persists the state of a business entity such an Order or a Customer as a sequence of state-changing events." | `official-reference` | event sourcing 채택 시스템의 영속화 모델 정의 | event sourcing 이 모든 도메인에 적합하다는 뜻은 아님 — drawback 인용 별도 |
|
|
| ES-OUTBOX-C2 | event 저장은 단일 operation 이므로 본질적으로 atomic — 즉 dual-write 문제가 발생하지 않는 구조 | [§Solution] "Since saving an event is a single operation, it is inherently atomic." | `official-reference` | event store 가 단일 transaction 단위로 event 를 추가하는 영속화 경계 | "DB + Kafka 두 시스템에 동시 쓰기가 자동으로 atomic" 이라는 뜻은 아님 — event store 단일 시스템 내부에서만 |
|
|
| ES-OUTBOX-C3 | 현재 상태는 events 를 replay 함으로써 재구성된다 (저장된 것은 events, 계산되는 것은 state) | [§Solution] "The application reconstructs an entity's current state by replaying the events." | `official-reference` | event sourcing 의 read path 메커니즘 | replay 비용이 항상 허용 가능하다는 뜻은 아님 — snapshot 필요성은 별도 |
|
|
| ES-OUTBOX-C4 | event store 에 event 가 저장되면 모든 관심 있는 subscriber 에게 전달된다 → 별도 발행 메커니즘(outbox/CDC) 의 역할이 event store 자체로 흡수 | [§Solution] "When a service saves an event in the event store, it is delivered to all interested subscribers." | `official-reference` | event store 가 내장 subscription 기능을 제공하는 구현 (EventStoreDB, Axon 등) | "subscriber 전달이 exactly-once" 라는 뜻은 아님 — delivery semantics 본 인용에 미명시 |
|
|
| ES-OUTBOX-C5 | event sourcing 은 event-driven architecture 구현의 핵심 문제(상태 변경 시 안정적 event 발행) 를 해결한다 | [§Resulting Context — Benefits] "It solves one of the key problems in implementing an event-driven architecture and makes it possible to reliably publish events whenever state changes." | `official-reference` | event-driven architecture 의 dual-write 문제 컨텍스트 | "outbox 보다 항상 우수하다" 는 뜻은 아님 — 트레이드오프 별도 |
|
|
| ES-OUTBOX-C6 | event store 는 query 가 어렵다 — 일반 query 가 entity state 재구성을 요구하기 때문 | [§Resulting Context — Drawbacks] "The event store is difficult to query since it requires typical queries to reconstruct the state of the business entities." | `official-reference` | event sourcing 의 read model 운영 부담 | CQRS read model 분리가 의무라는 뜻은 아님 — 권장 패턴일 뿐 |
|
|
|
|
## Usage Boundaries / 적용 경계
|
|
|
|
- **이 자료가 직접 증명하는 것**:
|
|
- `ES-OUTBOX-C1` ~ `C3`: event sourcing 의 정의·atomicity·replay 메커니즘
|
|
- `ES-OUTBOX-C4` ~ `C5`: event sourcing 이 outbox 와 같은 별도 발행 메커니즘의 필요성을 흡수한다는 사실
|
|
- `ES-OUTBOX-C6`: event sourcing 의 query 어려움 (CQRS / snapshot / projection 필요성의 근거)
|
|
- **이 자료가 증명하지 않는 것**:
|
|
- event sourcing 이 outbox/SKIP LOCKED 보다 "더 나은 선택" 이라는 일반적 권고
|
|
- 기존 CRUD 시스템에서 event sourcing 으로 마이그레이션 비용 구체적 산정
|
|
- event store 의 EOS (exactly-once) 보장 — 본 페이지는 delivery semantics 미명시
|
|
- Spring/JPA 기반 도메인에서 event sourcing 도입의 ORM 충돌 정도
|
|
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
|
|
- ca-tmpl 의 도메인이 event sourcing 에 적합한가 (금융/감사 로그 중심 vs 단순 CRUD)
|
|
- team 의 CQRS/projection 운영 경험 수준 — event sourcing 학습 곡선 평가
|
|
- event store 도구 선택 (EventStoreDB / Axon / Kafka-as-log) 의 운영 비용
|
|
|
|
## 메모 / Notes (내 프로젝트 해석)
|
|
|
|
> 본 섹션은 자료 직접 인용 아님. ca-tmpl 결정 컨텍스트 해석.
|
|
|
|
- 적용 시나리오: 도메인이 본질적으로 event-driven (금융 거래, 주문 상태 전이, 감사 로그가 핵심). 팀이 CQRS / projection 운영에 익숙한 경우.
|
|
- 장점:
|
|
- **outbox 불요** — event 자체가 저장 단위 (`ES-OUTBOX-C2` + `C4` 결합 해석)
|
|
- 완전한 audit log (모든 상태 변화가 보존)
|
|
- replay 로 신규 read model 구축 자유로움
|
|
- temporal query (과거 시점 상태 재구성) 가능
|
|
- 단점:
|
|
- **현재 상태 조회가 비싸다** (`ES-OUTBOX-C6`) → snapshot / projection 인프라 필요
|
|
- 학습 곡선 가파름 (CQRS, eventual consistency, projection 재구축 등)
|
|
- schema evolution (event 버전 관리) 부담
|
|
- 기존 CRUD 시스템에서 마이그레이션 비용 큼
|
|
- 일반적 ORM/JPA workflow 와 충돌
|
|
- ca-tmpl(SKIP LOCKED polling) 과의 차이:
|
|
- outbox 는 **기존 CRUD + 이벤트 발행** 하이브리드. event sourcing 은 **저장 모델 자체를 교체**.
|
|
- "보조 발행 메커니즘" 이 아니라 "도메인 모델 패러다임 전환" 이라 의사결정 스케일이 다름
|
|
- 운영 복잡도: 높음. event store + projection + snapshot 운영.
|
|
- exactly-once / at-least-once 보장 수준: 발행은 여전히 **at-least-once** 가정 안전 (본 페이지 미명시 — 별도 검증 필요).
|
|
- 외부 의존성 추가 여부: event store (EventStoreDB, Kafka as log, Axon 등) 또는 자체 구축.
|
|
- 결론: ca-tmpl 같은 기존 CRUD-based 도메인에 event sourcing 을 도입하는 것은 outbox 의 "대안" 이 아니라 "전혀 다른 도메인 설계 선택" 에 가까움. 트레이드오프 폭이 가장 큼.
|
|
|
|
## Related / 관련
|
|
|
|
- 같은 주제 다른 raw 자료:
|
|
- [[raw/company-tech-blogs/domain-event-sourcing-vs-cqrs-greg-young]] (event sourcing vs CQRS 구분 — Greg Young 원작자)
|
|
- [[raw/company-tech-blogs/outbox-confluent-kafka-connect-smt]] (대안 2: Kafka Connect SMT)
|
|
- [[raw/company-tech-blogs/outbox-netflix-domain-events-cdc]] (대안 6: Netflix DBLog)
|
|
- [[raw/company-tech-blogs/outbox-wix-engineering-debezium]] (대안 1 사례: Wix Debezium production)
|
|
- 인용하는 branch:
|
|
- [[raw/branch-notes/feature-domain-event-outbox-contract]]
|
|
- [[raw/branch-notes/feature-background-job-async-contract]]
|
|
- 인용하는 wiki: (미작성)
|