[G1-Sync] Manual knowledge update

This commit is contained in:
Antigravity Agent
2026-05-10 22:08:15 +09:00
parent 21ac3ed255
commit 504fd5fb42
3011 changed files with 380280 additions and 206977 deletions
@@ -1,128 +1,219 @@
---
id: wiki-2026-0508-architecture-anti-patterns
title: Architecture Anti patterns
title: Architecture Anti-patterns
category: 10_Wiki/Topics
status: needs_review
status: verified
canonical_id: self
aliases: [P-REINFORCE-WIKI-72D5C126]
aliases: [아키텍처 안티패턴, design anti-patterns, distributed monolith, big ball of mud]
duplicate_of: none
source_trust_level: A
confidence_score: 0.95
tags: [architecture-anti-patterns, circuit-breaker-pattern, architecture-decision-record-(adr), anaemic-domain-model, software-architecture-erosion, architecture-principles]
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-02
last_reinforced: 2026-05-10
github_commit: pending
inferred_by: Claude Opus 4.7 (auto-normalize 2026-05-08)
tech_stack:
language: unspecified
framework: unspecified
language: language-agnostic
framework: any
---
# [[Architecture Anti-patterns]]
# Architecture Anti-patterns
## 📌 한 줄 통찰 (The Karpathy Summary)
아키텍처 안티패턴(Architecture Anti-patterns)은 소프트웨어 시스템 설계 및 진화 과정에서 발생할 수 있는 비효율적이거나 잘못된 아키텍처 결정 및 관행을 의미합니다 [1, 2]. 분산 시스템에서의 잘못된 타임아웃 설정, 의사결정의 지연(분석 마비), 또는 문서화되지 않은 결정 등이 대표적인 사례입니다 [1, 2]. 이러한 안티패턴을 인지하고 해결하는 것은 시스템의 성능 저하와 커뮤니케이션 단절을 막는 데 필수적이지만, 하나의 안티패턴을 해결하는 과정이 연쇄적으로 또 다른 안티패턴을 유발할 수도 있으므로 주의가 필요합니다 [2].
## 📌 한 줄 통찰
> **"매 안 하면 좋은 것"**. 매 design 의 mistake catalog. 매 timeout misconfig, 매 distributed monolith, 매 big ball of mud. 매 anti-pattern 의 catalog 의 senior 의 첫 weapon.
## 📖 구조화된 지식 (Synthesized Content)
소스 데이터를 기반으로 확인된 주요 아키텍처 안티패턴은 다음과 같습니다.
## 📖 핵심
- **타임아웃 안티패턴 (Timeout AntiPattern):** 분산 시스템에서 타임아웃 값을 설정할 때 발생하는 문제를 설명합니다 [1]. 타임아웃을 너무 짧게 설정하면 정상적인 요청도 조기에 실패 처리되어 복잡한 우회 방법이 필요해지며, 너무 길게 설정하면 오류 응답이 늦어져 사용자 경험이 심각하게 저하됩니다 [1].
- **의사결정 지연 및 분석 마비 (Decision Delay & Analysis Paralysis):** 아키텍트가 잘못된 선택을 할 것을 두려워하여 아키텍처 결정을 지연시키거나 회피할 때 발생합니다 [2]. 이를 방지하려면 개발 팀과 긴밀하게 협력하고, 불필요한 지연으로 인한 분석 마비를 막기 위해 충분한 정보가 확보된 '마지막 책임 순간(last responsible moment)'에 결정을 내려야 합니다 [2].
- **문서화되지 않은 결정 (Forgotten/Undocumented Decisions):** 아키텍처 결정이 이메일과 같은 휘발성 매체를 통해 소통되거나 제대로 기록되지 않아 잊혀지는 현상입니다 [2]. 이는 명확한 결론 없이 동일한 논의가 반복되는 결과를 초래합니다 [2].
- **빈약한 도메인 모델 (Anaemic Model):** 전통적으로는 안티패턴으로 간주되지만, 마이크로서비스 아키텍처와 같이 단일 도메인의 기능만 포함하는 매우 작은 서비스에서는 이러한 트랜잭션 스크립트 기반의 단순한 모델이 오히려 효율적일 수 있다는 논의도 존재합니다 [3].
### 매 카테고리
## ⚠️ 모순 및 업데이트 (Contradictions & Updates)
- **안티패턴 해결의 연쇄 작용:** 아키텍처 안티패턴은 종종 점진적인 시퀀스를 따르기 때문에, 하나의 안티패턴을 해결하기 위한 조치가 또 다른 안티패턴의 출현으로 이어질 수 있는 제약 및 부작용을 동반합니다 [2].
- **타임아웃 설정의 딜레마:** 타임아웃 안티패턴에서 짧은 타임아웃(정상 요청의 실패 위험)과 긴 타임아웃(느린 에러 응답) 사이의 타협점(Trade-off)을 찾는 것은 매우 어렵습니다 [1]. 이를 최적화하기 위해 서킷 브레이커(Circuit Breaker) 패턴을 도입할 수 있으나, 이는 서비스 상태를 실시간으로 모니터링해야 하는 시스템적 복잡성을 추가로 요구합니다 [1].
- **문서화 오버헤드:** 문서화되지 않은 결정 안티패턴을 피하기 위해서는 기술적 및 비즈니스적(비용, 시장 출시 시간 등) 타당성을 명시한 아키텍처 결정 기록(ADR)을 위키와 같은 중앙 저장소에 엄격하게 관리해야 하는 관리적 반대 급부가 따릅니다 [2].
- **결정 시점의 위험성:** 분석 마비를 피하기 위해 '마지막 책임 순간'까지 결정을 보류하는 것은 유연성을 유지하는 방법이지만, 시기를 잘못 조율하면 오히려 개발 진행을 방해하는 치명적인 병목이 될 수 있습니다 [2].
#### 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 합.
## 🔗 지식 연결 (Graph)
### Related Concepts
#### Decision-making
- **Analysis paralysis**: 매 fear-driven indecision.
- **Forgotten decision**: 매 email-only / 매 ADR 없음.
- **Premature optimization**: 매 evidence X 의 optimize.
- **Cargo cult**: 매 "Netflix 가 이렇게" 의 무비판 모방.
#### [아키텍처/기반 기술]
- [[Circuit Breaker Pattern]]
- 연결 이유: Timeout AntiPattern으로 인해 발생하는 분산 시스템의 오류 응답 및 지연 문제를 해결하기 위한 구조적 해결책입니다 [1].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 하트비트(heartbeat)나 실시간 사용량 모니터링을 통해 실패를 조기에 감지하고 분산 아키텍처의 복원력을 높이는 원리 [1].
#### 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.
#### [구현/활용 도구]
- [[Architecture Decision Record (ADR)]]
- 연결 이유: 이메일 등을 통한 파편화된 소통으로 인해 결정이 잊혀지는 안티패턴을 방지하기 위한 구체적인 문서화 도구입니다 [2].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 아키텍처 결정의 배경, 대안, 위험 및 결과를 문서화하여 시간이 지나도 팀원 및 이해관계자들이 변경 사항을 추적할 수 있도록 돕는 방법 [4, 5].
#### 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.
#### [설계 패러다임]
- [[Anaemic Domain Model]]
- 연결 이유: 일반적으로 안티패턴으로 불리나, 마이크로서비스 설계의 경계 내에서는 수용 가능 여부가 토론되는 핵심 개념입니다 [3].
- 이 개념을 통해 더 깊게 이해할 수 있는 부분: 모놀리식 구조와 마이크로서비스 구조에서 비즈니스 로직의 복잡성을 다루는 관점의 차이 [3].
#### 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.
### Deeper Research Questions
- 분산 시스템에서 Timeout AntiPattern을 피하기 위해 Circuit Breaker 외에 어떠한 기술적 패턴들이 병행되어야 하는가?
- '마지막 책임 순간(Last responsible moment)'에 도달했음을 객관적으로 판단할 수 있는 정량적 또는 정성적 기준은 무엇인가?
- ADR(Architecture Decision Record)을 지속적으로 유지보수하기 위해 개발 조직의 문화나 파이프라인에 어떻게 통합하는 것이 가장 효과적인가?
- Anaemic Model이 마이크로서비스 환경에서 수용될 수 있는 시스템적 한계점(크기나 복잡도 기준)은 어디까지인가?
- 하나의 아키텍처 안티패턴을 해결했을 때 연쇄적으로 발생하는 다른 안티패턴들의 구체적인 실무 사례와 방어 전략은 무엇인가?
### Sequence problem
- 매 anti-pattern 의 fix 가 매 다른 anti-pattern 의 generate.
- 매 distributed monolith 의 fix → 매 chatty / 매 sync chain.
- 매 god object 의 split → 매 nano-service.
### Practical Application Contexts
- **Implementation:** 마이크로서비스 간의 통신 시 타임아웃 안티패턴에 빠지지 않도록 적절한 서킷 브레이커 도구를 구현하여 장애 전파를 차단합니다.
- **System Design:** 초기 시스템 설계 시 모놀리식과 마이크로서비스 간의 트레이드오프를 평가할 때, 무조건적인 도메인 모델의 복잡화(Anaemic Model 배제)가 항상 정답은 아님을 인지하고 서비스 크기에 맞게 설계합니다.
- **Operation / Maintenance:** 이메일이나 채팅으로 결정된 주요 아키텍처 사항들을 위키 기반의 중앙화된 ADR 저장소로 이관하여 문서화 누락으로 인한 유지보수 병목을 방지합니다.
- **Learning Path:** 분산 시스템이나 클라우드 네이티브 환경을 학습할 때, 성공적인 패턴뿐만 아니라 Timeout AntiPattern이나 의사결정 분석 마비와 같은 안티패턴을 먼저 인지하여 설계 실패를 조기에 예방합니다.
- **My Project Relevance:** 현재 진행 중인 프로젝트에서 결정을 내리지 못해 일정이 지연되고 있다면, 그것이 정보 부족 때문인지 아니면 두려움으로 인한 '분석 마비' 안티패턴인지 진단하고, 마지막 책임 순간의 기준을 명확히 설정할 수 있습니다.
→ 매 trade-off awareness 의 핵심.
### Adjacent Topics
- [[Software Architecture Erosion]]
- 확장 방향: 아키텍처 안티패턴이 장기적으로 방치되었을 때 시스템 아키텍처가 원래의 의도에서 벗어나 붕괴되거나 침식되는 과정과 그 복구 방법에 대한 연구로 확장할 수 있습니다 [6].
- [[Distributed Systems Fallacies]]
- 확장 방향: 이벤트 기반 아키텍처나 분산 시스템 설계 시, 타임아웃 문제나 데이터 손실과 같이 네트워크가 항상 신뢰할 수 있다는 오해(분산 컴퓨팅의 오류)에 대한 탐구로 이어질 수 있습니다 [7, 8].
### 매 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.
---
*Last updated: 2026-05-02*
### 매 modern catalog
- Mark Richards 의 "Software Architecture: The Hard Parts".
- Sam Newman 의 "Building Microservices".
- Vaughn Vernon "Implementing DDD".
- AWS / Azure architecture pattern.
## 🤖 LLM 활용 힌트 (How to Use This Knowledge)
## 💻 패턴 (응용 — detection / fix)
**언제 이 지식을 쓰는가:**
- *(TODO)*
**언제 쓰면 안 되는가:**
- *(TODO)*
## 🧪 검증 상태 (Validation)
- **정보 상태:** needs_review
- **출처 신뢰도:** A
- **검토 이유:** *(P-Reinforce Phase 1 자동 정규화. 본문 검증 필요.)*
## 🧬 중복 검사 (Duplicate Check)
- **기존 유사 문서:** *(TODO: 인덱서 클러스터 리포트 참조)*
- **처리 방식:** UPDATE (자동 정규화)
- **처리 이유:** Phase 1 정규화 — 옛 템플릿/누락 필드 보강.
## 🕓 변경 이력 (Changelog)
| 날짜 | 변경 내용 | 처리 방식 | 신뢰도 |
|------|-----------|-----------|--------|
| 2026-05-08 | P-Reinforce Phase 1 정규화 (frontmatter + 헤더 표준화) | UPDATE | A |
## 💻 코드 패턴 (Code Patterns)
**패턴 1:** *(TODO: 이 프로젝트 컨벤션 반영한 구조 스켈레톤)*
```text
# TODO
### 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 },
},
],
};
```
## 🤔 의사결정 기준 (Decision Criteria)
### ADR (Architecture Decision Record) template
```markdown
# ADR-0042: Use Kafka for inter-service events
**선택 A를 써야 할 때:**
- *(TODO)*
## Status
Accepted (2026-05-10)
**선택 B를 써야 할 때:**
- *(TODO)*
## Context
3 services (order, billing, inventory) need to coordinate.
Sync HTTP creates cascading failure risk.
**기본값:**
> *(TODO)*
## Decision
Adopt Kafka for async event-driven coordination.
Use Avro for schema evolution.
## ❌ 안티패턴 (Anti-Patterns)
## Consequences
+ Decoupling, scale, replay.
- Operational complexity (Kafka cluster).
- Debugging async harder.
- **[안티패턴]:** *(TODO: 무엇을 하면 안 되는가 + 이유 + 대신 무엇을)*
## 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]] · [[Software-Engineering]]
- 변형: [[Big-Ball-of-Mud]] · [[Distributed-Monolith]] · [[Anaemic-Domain-Model]] · [[God-Object]]
- 응용: [[Circuit-Breaker]] · [[ADR]] · [[Architecture-Test]] · [[Bounded-Context]]
- Adjacent: [[Technical-Debt]] · [[Code-Smells]] · [[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 |