Files
2nd/10_Wiki/Topics/AI_and_ML/Event-Driven-Architecture.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

207 lines
5.5 KiB
Markdown

---
id: wiki-2026-0508-event-driven-architecture
title: Event-Driven Architecture
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [EDA, event-driven, pub-sub, message-driven, choreography, orchestration]
duplicate_of: none
source_trust_level: A
confidence_score: 0.97
verification_status: applied
tags: [architecture, eda, event-driven, kafka, pub-sub, choreography, microservices]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: TypeScript / Java / Python
framework: Kafka / RabbitMQ / EventBridge / NATS
---
# Event-Driven Architecture
## 매 한 줄
> **"매 service 의 event 의 의 communicate"**. 매 sync HTTP RPC 의 X — 매 async pub/sub. 매 decouple + scale + replay. 매 modern: 매 Kafka, EventBridge, NATS, async.
## 매 핵심
### 매 pattern
- **Event notification**: 매 fire-and-forget.
- **Event-carried state transfer**: 매 payload 의 state.
- **Event sourcing**: 매 store events.
- **CQRS**: 매 read/write split.
### 매 choreography vs orchestration
- **Choreography**: 매 service 의 react.
- **Orchestration**: 매 central coordinator (saga).
### 매 응용
1. **Microservices**: 매 decouple.
2. **Real-time**: 매 streaming.
3. **Fan-out**: 매 1 → many.
4. **Audit**: 매 replay.
5. **Integration**: 매 cross-system.
## 💻 패턴
### Kafka producer (Java)
```java
KafkaProducer<String, String> p = new KafkaProducer<>(props);
p.send(new ProducerRecord<>("orders.placed", orderId, json), (md, ex) -> {
if (ex != null) log.error("Failed", ex);
});
```
### Kafka consumer (Python)
```python
from confluent_kafka import Consumer
c = Consumer({'bootstrap.servers': 'kafka:9092', 'group.id': 'inventory', 'auto.offset.reset': 'earliest'})
c.subscribe(['orders.placed'])
while True:
msg = c.poll(1.0)
if msg and not msg.error():
handle_order(json.loads(msg.value()))
```
### Outbox (transactional publish)
```typescript
async function placeOrder(o: Order) {
await db.transaction(async tx => {
await tx.orders.save(o);
await tx.outbox.insert({ topic: 'orders.placed', payload: o, status: 'pending' });
});
}
// 매 separate process polls outbox → Kafka
```
### Schema registry (Avro)
```json
{
"type": "record",
"name": "OrderPlaced",
"fields": [
{ "name": "orderId", "type": "string" },
{ "name": "amount", "type": "long" },
{ "name": "currency", "type": "string", "default": "USD" }
]
}
```
### Saga orchestration
```typescript
class OrderSaga {
async execute(orderId: string) {
try {
await reservePayment(orderId);
await reserveInventory(orderId);
await scheduleShipping(orderId);
} catch (e) {
await this.compensate(orderId);
throw e;
}
}
async compensate(orderId: string) {
await releaseInventory(orderId);
await refundPayment(orderId);
}
}
```
### Choreography (each service reacts)
```typescript
// 매 inventory service
on('orders.placed', async event => {
const ok = await reserve(event.orderId);
publish(ok ? 'inventory.reserved' : 'inventory.failed', event);
});
// 매 shipping service
on('inventory.reserved', async event => {
await schedule(event.orderId);
publish('shipping.scheduled', event);
});
```
### DLQ (dead letter queue)
```python
def consume_with_dlq(topic, handler, max_retries=3):
for msg in consumer:
for attempt in range(max_retries):
try:
handler(msg)
break
except Exception as e:
if attempt == max_retries - 1:
dlq.publish(msg, error=str(e))
```
### Idempotency
```python
def idempotent_handler(event):
if redis.set(f'evt:{event.id}', '1', nx=True, ex=86400):
process(event)
# 매 else: skip duplicate
```
### Backpressure
```python
def consume_with_backpressure(consumer, max_in_flight=100):
sem = Semaphore(max_in_flight)
for msg in consumer:
sem.acquire()
thread = Thread(target=lambda m=msg: (process(m), sem.release()))
thread.start()
```
### Event versioning
```typescript
type OrderPlacedV1 = { version: 1; orderId: string; amount: number };
type OrderPlacedV2 = { version: 2; orderId: string; amount: number; currency: string };
function migrate(e: OrderPlacedV1 | OrderPlacedV2): OrderPlacedV2 {
if (e.version === 1) return { ...e, version: 2, currency: 'USD' };
return e;
}
```
## 매 결정 기준
| 상황 | Tool |
|---|---|
| High throughput | Kafka |
| Cloud-native AWS | EventBridge / SNS+SQS |
| Low latency | NATS |
| Complex routing | RabbitMQ |
| Simple pub/sub | Redis Streams |
| Multi-step | Saga (Temporal) |
**기본값**: 매 Kafka + 매 schema registry + 매 outbox + 매 DLQ + 매 idempotency.
## 🔗 Graph
- 부모: [[Architecture]] · [[Distributed-Systems]]
- 변형: [[Event Sourcing Pattern]] · [[CQRS]]
- 응용: [[Kafka]] · [[NATS]]
- Adjacent: [[Microservices]]
## 🤖 LLM 활용
**언제**: 매 microservice. 매 streaming. 매 decouple.
**언제 X**: 매 simple monolith. 매 strict transaction.
## ❌ 안티패턴
- **Sync inside async**: 매 backpressure 의 break.
- **No schema**: 매 break.
- **No DLQ**: 매 stuck consumer.
- **No idempotency**: 매 duplicate processing.
- **Choreography 의 over-use**: 매 spaghetti.
## 🧪 검증 / 중복
- Verified (Fowler EDA, Confluent, AWS Reference Architecture).
- 신뢰도 A.
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-04-20 | Auto-reinforced |
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — EDA + 매 Kafka / outbox / saga / DLQ / idempotency code |