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>
220 lines
7.0 KiB
Markdown
220 lines
7.0 KiB
Markdown
---
|
|
id: wiki-2026-0508-architecture-anti-patterns
|
|
title: Architecture Anti-patterns
|
|
category: 10_Wiki/Topics
|
|
status: verified
|
|
canonical_id: self
|
|
aliases: [아키텍처 안티패턴, design anti-patterns, distributed monolith, big ball of mud]
|
|
duplicate_of: none
|
|
source_trust_level: B
|
|
confidence_score: 0.9
|
|
verification_status: applied
|
|
tags: [architecture, anti-patterns, distributed-systems, microservices, adr, code-smell, technical-debt]
|
|
raw_sources: []
|
|
last_reinforced: 2026-05-10
|
|
github_commit: pending
|
|
tech_stack:
|
|
language: language-agnostic
|
|
framework: any
|
|
---
|
|
|
|
# Architecture Anti-patterns
|
|
|
|
## 📌 한 줄 통찰
|
|
> **"매 안 하면 좋은 것"**. 매 design 의 mistake catalog. 매 timeout misconfig, 매 distributed monolith, 매 big ball of mud. 매 anti-pattern 의 catalog 의 senior 의 첫 weapon.
|
|
|
|
## 📖 핵심
|
|
|
|
### 매 카테고리
|
|
|
|
#### Distributed system
|
|
- **Distributed monolith**: 매 microservice 가 sync coupling — 매 worst of both.
|
|
- **Chatty service**: 매 N+1 inter-service call.
|
|
- **Wrong timeout**: 매 too short = false fail / too long = bad UX.
|
|
- **Shared database**: 매 service 가 같은 DB → 매 coupling.
|
|
- **No circuit breaker**: 매 cascading failure.
|
|
- **Synchronous chain**: 매 5 service hop = 매 latency 합.
|
|
|
|
#### Decision-making
|
|
- **Analysis paralysis**: 매 fear-driven indecision.
|
|
- **Forgotten decision**: 매 email-only / 매 ADR 없음.
|
|
- **Premature optimization**: 매 evidence X 의 optimize.
|
|
- **Cargo cult**: 매 "Netflix 가 이렇게" 의 무비판 모방.
|
|
|
|
#### Code structure
|
|
- **Big ball of mud**: 매 boundary X.
|
|
- **God object**: 매 single class 의 모든 logic.
|
|
- **Anaemic model**: 매 entity 가 data 만 (case-by-case).
|
|
- **Spaghetti**: 매 control flow tangled.
|
|
- **Lava flow**: 매 dead code + commented-out.
|
|
|
|
#### Microservice 특화
|
|
- **Nano-service**: 매 너무 작 — 매 communication 의 logic 의 dominate.
|
|
- **Entity service**: 매 1 entity = 1 service (vs business capability).
|
|
- **Sync everywhere**: 매 async 의 부재.
|
|
- **No bounded context**: 매 model 의 leak.
|
|
- **Versioning chaos**: 매 breaking change 의 coordination X.
|
|
|
|
#### Data
|
|
- **Data in flight**: 매 in-memory 의 single source of truth.
|
|
- **Eventual consistency 의 ignore**: 매 user 의 see stale.
|
|
- **Cache stampede**: 매 expire 시 동시 fetch.
|
|
- **Read-modify-write race**: 매 lost update.
|
|
|
|
### Sequence problem
|
|
- 매 anti-pattern 의 fix 가 매 다른 anti-pattern 의 generate.
|
|
- 매 distributed monolith 의 fix → 매 chatty / 매 sync chain.
|
|
- 매 god object 의 split → 매 nano-service.
|
|
|
|
→ 매 trade-off awareness 의 핵심.
|
|
|
|
### 매 detect 방법
|
|
- **Architecture test**: dependency-cruiser, ArchUnit.
|
|
- **Dependency graph**: 매 cycle / 매 hub.
|
|
- **Latency analysis**: 매 hop count.
|
|
- **Code metric**: 매 cyclomatic / 매 LOC / 매 fan-out.
|
|
- **Tracing**: 매 distributed trace 의 path.
|
|
- **Postmortem catalog**: 매 incident pattern.
|
|
|
|
### 매 modern catalog
|
|
- Mark Richards 의 "Software Architecture: The Hard Parts".
|
|
- Sam Newman 의 "Building Microservices".
|
|
- Vaughn Vernon "Implementing DDD".
|
|
- AWS / Azure architecture pattern.
|
|
|
|
## 💻 패턴 (응용 — detection / fix)
|
|
|
|
### Architecture test
|
|
```js
|
|
// .dependency-cruiser.js
|
|
module.exports = {
|
|
forbidden: [
|
|
{
|
|
name: 'no-domain-to-infrastructure',
|
|
severity: 'error',
|
|
from: { path: '^src/domain' },
|
|
to: { path: '^src/infrastructure' },
|
|
},
|
|
{
|
|
name: 'no-circular',
|
|
severity: 'error',
|
|
from: {},
|
|
to: { circular: true },
|
|
},
|
|
],
|
|
};
|
|
```
|
|
|
|
### ADR (Architecture Decision Record) template
|
|
```markdown
|
|
# ADR-0042: Use Kafka for inter-service events
|
|
|
|
## Status
|
|
Accepted (2026-05-10)
|
|
|
|
## Context
|
|
3 services (order, billing, inventory) need to coordinate.
|
|
Sync HTTP creates cascading failure risk.
|
|
|
|
## Decision
|
|
Adopt Kafka for async event-driven coordination.
|
|
Use Avro for schema evolution.
|
|
|
|
## Consequences
|
|
+ Decoupling, scale, replay.
|
|
- Operational complexity (Kafka cluster).
|
|
- Debugging async harder.
|
|
|
|
## Alternatives considered
|
|
1. RabbitMQ — simpler but less throughput.
|
|
2. SQS — vendor lock-in.
|
|
3. Sync HTTP — original problem.
|
|
```
|
|
|
|
### Circuit breaker (anti-pattern fix)
|
|
```ts
|
|
class CircuitBreaker {
|
|
state: 'closed' | 'open' | 'half-open' = 'closed';
|
|
failures = 0;
|
|
lastFailure = 0;
|
|
|
|
async call<T>(fn: () => Promise<T>): Promise<T> {
|
|
if (this.state === 'open') {
|
|
if (Date.now() - this.lastFailure > 30_000) this.state = 'half-open';
|
|
else throw new CircuitOpen();
|
|
}
|
|
try {
|
|
const result = await fn();
|
|
if (this.state === 'half-open') this.state = 'closed';
|
|
this.failures = 0;
|
|
return result;
|
|
} catch (e) {
|
|
this.failures++;
|
|
this.lastFailure = Date.now();
|
|
if (this.failures > 5) this.state = 'open';
|
|
throw e;
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Detect distributed monolith
|
|
```python
|
|
def detect_distributed_monolith(services, traces):
|
|
"""매 sync coupling chain 의 detect"""
|
|
for trace in traces:
|
|
sync_chain = [s for s in trace.spans if s.kind == 'sync']
|
|
if len(sync_chain) > 3:
|
|
yield ('long sync chain', trace.id, sync_chain)
|
|
|
|
# 매 deploy coupling
|
|
deploy_pairs = collections.Counter()
|
|
for incident in incidents:
|
|
if len(incident.affected_services) > 1:
|
|
for pair in combinations(incident.affected_services, 2):
|
|
deploy_pairs[pair] += 1
|
|
|
|
return deploy_pairs.most_common(5)
|
|
```
|
|
|
|
## 🤔 결정 기준
|
|
| 안티패턴 | 해결 |
|
|
|---|---|
|
|
| Distributed monolith | Async event + bounded context |
|
|
| Wrong timeout | Tiered timeout + circuit breaker |
|
|
| Forgotten decision | ADR + central wiki |
|
|
| Analysis paralysis | Last responsible moment + spike |
|
|
| God object | Refactor by responsibility |
|
|
| Nano-service | Merge by business capability |
|
|
| Cache stampede | Probabilistic refresh, lock |
|
|
|
|
**기본값**: 매 ADR + architecture test + tracing + postmortem.
|
|
|
|
## 🔗 Graph
|
|
- 부모: [[Architecture-Styles]]
|
|
- 변형: [[Big-Ball-of-Mud]] · [[Distributed-Monolith]] · [[Anaemic-Domain-Model]] · [[God-Object]]
|
|
- 응용: [[Circuit-Breaker]] · [[ADR]] · [[Bounded-Context]]
|
|
- Adjacent: [[Technical_Debt|Technical-Debt]] · [[Code-Smells]] · [[Refactoring_Best_Practices|Refactoring]] · [[Postmortem]]
|
|
|
|
## 🤖 LLM 활용
|
|
**언제**: 매 architecture review. 매 design decision. 매 incident 의 root cause analysis.
|
|
**언제 X**: 매 simple project (대부분 의 anti-pattern 의 N/A).
|
|
|
|
## ❌ 안티패턴 (meta)
|
|
- **모든 anti-pattern 의 fix**: 매 trade-off 의 ignore.
|
|
- **Cargo cult**: 매 "최선" 의 context 의 ignore.
|
|
- **No ADR**: 매 future-self 의 confusion.
|
|
- **Architecture astronaut**: 매 over-design.
|
|
- **YAGNI 의 무시**: 매 future hypothetical 의 design.
|
|
|
|
## 🧪 검증 / 중복
|
|
- Verified (Mark Richards, Sam Newman, AWS Well-Architected).
|
|
- 신뢰도 B.
|
|
- Related: [[Architecture-Styles]] · [[Anaemic-Domain-Model]] · [[Circuit-Breaker]].
|
|
|
|
## 🕓 Changelog
|
|
| 날짜 | 변경 |
|
|
|---|---|
|
|
| 2026-05-08 | Phase 1 |
|
|
| 2026-05-10 | Manual cleanup — 카테고리 + 매 distributed / decision / data + ADR + circuit breaker |
|