f8b21af4be
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>
5.5 KiB
5.5 KiB
id, title, category, status, canonical_id, aliases, duplicate_of, source_trust_level, confidence_score, verification_status, tags, raw_sources, last_reinforced, github_commit, tech_stack
| id | title | category | status | canonical_id | aliases | duplicate_of | source_trust_level | confidence_score | verification_status | tags | raw_sources | last_reinforced | github_commit | tech_stack | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| wiki-2026-0508-event-driven-architecture | Event-Driven Architecture | 10_Wiki/Topics | verified | self |
|
none | A | 0.97 | applied |
|
2026-05-10 | pending |
|
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).
매 응용
- Microservices: 매 decouple.
- Real-time: 매 streaming.
- Fan-out: 매 1 → many.
- Audit: 매 replay.
- Integration: 매 cross-system.
💻 패턴
Kafka producer (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)
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)
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)
{
"type": "record",
"name": "OrderPlaced",
"fields": [
{ "name": "orderId", "type": "string" },
{ "name": "amount", "type": "long" },
{ "name": "currency", "type": "string", "default": "USD" }
]
}
Saga orchestration
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)
// 매 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)
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
def idempotent_handler(event):
if redis.set(f'evt:{event.id}', '1', nx=True, ex=86400):
process(event)
# 매 else: skip duplicate
Backpressure
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
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 |