진화형 아키텍처(Evolutionary Architecture)와 피트니스 함수
1. 개요
진화형 아키텍처는 여러 차원(dimension)에 걸쳐 일어나는 변경을 '안내된(guided)·점진적(incremental)' 방식으로 지원하도록 설계된 아키텍처이며, 그 '안내'의 핵심 수단이 아키텍처 품질 속성을 객관적으로 측정하는 피트니스 함수(fitness function)다.
소프트웨어 아키텍처는 오랫동안 "처음에 올바르게 설계하면 오래 버틴다"는 전제를 깔고 있었다. 그러나 클라우드·마이크로서비스·지속적 배포가 보편화되면서 요구사항·기술·조직·규제가 분기 단위가 아니라 주·일 단위로 바뀌는 환경이 되었고, '초기 설계의 완결성'이라는 전제 자체가 무너졌다. 변화가 상수가 된 세계에서 아키텍처의 성패는 "얼마나 완벽하게 설계했는가"가 아니라 "얼마나 안전하게 계속 바꿀 수 있는가"로 이동했다. 진화형 아키텍처는 바로 이 질문에 답하기 위해 Rebecca Parsons·Neal Ford·Patrick Kua·Pramod Sadalage가 체계화한 접근으로, 2017년 초판과 2022년 2판의 『Building Evolutionary Architectures』가 이론적 토대다.
핵심 통찰은 '진화(evolution)'를 생물학적 은유 이상으로 공학화했다는 점이다. 유전 알고리즘이 세대마다 해(solution)의 적합도를 수치로 평가해 더 나은 방향으로 선택압을 주듯, 아키텍처도 매 변경마다 품질 속성의 적합도를 자동으로 측정해 허용 가능한 변경만 통과시키면 시스템은 의도한 특성을 유지하며 진화할 수 있다. 즉 피트니스 함수는 "이 변경이 아키텍처적으로 괜찮은가"를 사람의 주관적 리뷰가 아니라 실행 가능한 검증(executable check)으로 환원한 장치다.
진화형 아키텍처의 정의는 세 가지 성질로 분해된다. 첫째 안내된(guided) — 변경이 아무 방향으로나 일어나지 않도록 피트니스 함수가 방향을 잡아 준다. 둘째 점진적(incremental) — 작은 단위로 만들고 작은 단위로 배포해 변경 폭을 통제한다. 셋째 다차원(multiple dimensions) — 기술뿐 아니라 데이터·보안·운영·성능 등 여러 품질 축을 동시에 보전한다. 이 세 성질을 묶는 상위 개념이 "변경을 1급 설계 관심사로 승격한다"는 사고방식이며, 기술사는 이를 전통적 '한 번 설계' 모델과 대비해 설명할 수 있어야 한다.
2. 전체 구조: 안내된 변경·점진적 변경·다차원
진화형 아키텍처의 전체 구조는 '아키텍처 목표 → 피트니스 함수 → 안내된 점진적 변경 → 운영 시스템 → 관측 피드백'이 하나의 닫힌 루프를 이루는 형태다. 아래 그림은 품질 속성 요구사항과 여러 특성 차원이 피트니스 함수 집합으로 수렴하고, 그 결과가 변경의 통과·차단을 결정하며, 운영 중 수집된 지표가 다시 피트니스 함수로 환류되는 구조를 보여 준다.
flowchart TB
subgraph DIM["아키텍처 특성 차원"]
D1["기술: 결합도·순환참조"]
D2["보안: 의존성 취약점"]
D3["운영: 가용성·확장성"]
D4["성능: 응답시간 p99"]
D5["데이터: 스키마 진화"]
end
GOAL["아키텍처 목표\n(품질 속성 요구사항)"] --> FF["피트니스 함수 집합\n(객관적 적합성 측정)"]
DIM --> FF
FF -->|통과| CHANGE["안내된 점진적 변경\n(배포 파이프라인 통과)"]
FF -->|실패| BLOCK["변경 차단·피드백"]
CHANGE --> SYS["운영 중 시스템"]
SYS -->|관측 지표 수집| FF
BLOCK -.->|수정 후 재시도| CHANGE
안내된 변경은 변경의 자유도를 품질 속성이라는 울타리 안에 가두는 원리다. 개발자는 기능을 자유롭게 바꾸되, 피트니스 함수가 정의한 경계(예: "프레젠테이션 계층은 영속성 계층을 직접 참조할 수 없다", "서비스 간 순환 의존이 0이어야 한다")를 넘으면 변경이 자동으로 거부된다. 이때 중요한 것은 피트니스 함수가 '금지 목록'이 아니라 '보존해야 할 아키텍처 특성의 정의'라는 점이다. 특성을 명시적으로 선언해 두면, 시간이 지나 담당자가 바뀌어도 설계 의도가 코드와 파이프라인 속에 '살아 있는 문서'로 유지된다.
점진적 변경은 두 측면을 동시에 요구한다. 개발 측면에서는 작은 단위로 테스트 가능하게 만들어야 하고, 운영 측면에서는 작은 단위로 안전하게 배포·회수할 수 있어야 한다. 전자는 모듈화·낮은 결합도·자동화 테스트가, 후자는 [[ci-cd-pipeline]]·[[feature-flag]]·카나리·블루그린 같은 배포 메커니즘이 뒷받침한다. 점진성이 확보되지 않으면 피트니스 함수가 아무리 좋아도 '큰 덩어리 변경'의 위험을 통제할 수 없으므로, 점진적 변경 역량은 진화형 아키텍처의 전제 조건이다.
다차원 보전은 아키텍처가 단일 품질이 아니라 상충하는 여러 품질의 균형이라는 사실을 반영한다. 아래 표는 대표적 차원과 각 차원에서 흔히 쓰이는 피트니스 함수의 예다.
| 차원 | 보전 대상 특성 | 피트니스 함수 예시 | 측정 수단 |
|---|---|---|---|
| 기술(코드) | 모듈 경계·결합도 | "UI→DB 직접 의존 0건", 순환 참조 0 | ArchUnit·dependency-cruiser |
| 성능 | 응답시간·처리량 | "p99 지연 < 100ms" | 부하 테스트·APM |
| 보안 | 취약점·정책 | "Critical CVE 의존성 0건" | SCA·정책 코드화(OPA) |
| 운영 | 가용성·복원력 | "장애 주입 시 SLO 유지" | 카오스 실험 |
| 데이터 | 스키마 호환성 | "역호환 깨지는 스키마 변경 차단" | 스키마 레지스트리 검증 |
이처럼 차원별로 '무엇을, 어떤 임계값으로, 어떤 도구로' 지킬지를 선언하면 아키텍처 거버넌스가 추상적 구호에서 실행 가능한 규칙으로 바뀐다.
3. 아키텍처 피트니스 함수의 분류와 동작
피트니스 함수는 단일한 형태가 아니라 여러 축으로 분류되며, 그 조합으로 거버넌스 전략이 결정된다. 가장 널리 쓰이는 구분은 범위(scope) 축의 원자적(atomic)·전체적(holistic), 실행 시점(cadence) 축의 촉발(triggered)·연속(continual)이다.
원자적 피트니스 함수는 하나의 아키텍처 특성을 독립적으로 검증한다. 예컨대 "서비스 A는 서비스 B의 내부 패키지를 import할 수 없다"는 규칙은 단일 관심사를 보므로 단위 테스트처럼 빠르게 실행된다. 반면 전체적 피트니스 함수는 여러 특성이 상호작용하는 통합 지점을 함께 본다. "인증 서비스와 결제 서비스가 함께 동작할 때 전체 트랜잭션의 보안·지연 조건을 동시에 만족하는가" 같은 검증이 여기에 속하며, 통합 환경에서 실행되므로 비용이 크지만 조합에서만 드러나는 결함을 잡는다.
실행 시점 축에서 촉발형은 커밋·배포 같은 특정 이벤트에 반응해 실행된다. 대부분의 원자적 규칙이 여기에 해당하며 배포 파이프라인 단계로 들어간다. 연속형은 이벤트와 무관하게 운영 중 상시 측정한다. 운영 환경에서 p99 지연이나 가용성을 모니터링하다가 SLO를 위반하면 경보를 내는 것이 전형적 예로, 관측성([[opentelemetry-observability]]) 인프라와 결합한다. 그 밖에 코드와 무관하게 주기적으로 실행되는 시간형(temporal)(예: 매월 암호 라이브러리 만료·사용 중단 점검), 정적 분석으로 끝나는 정적(static) 대 실행해 봐야 하는 동적(dynamic), 사람이 수행하는 수동(manual) 대 자동(automated) 구분이 있다. 현실의 전략은 "자동·원자적·촉발형"을 기본으로 하되, 자동화가 어려운 특성만 수동·시간형으로 보완하는 식으로 조합한다.
아래 그림은 이들 피트니스 함수가 배포 파이프라인과 운영 환경에 배치되어 거버넌스를 자동화하는 모습을 보여 준다.
flowchart LR
DEV["개발자 커밋"] --> VCS["형상관리(Git)"]
VCS --> CI["CI 파이프라인"]
subgraph STAGE["피트니스 함수 게이트"]
direction TB
S1["원자적·정적\n(ArchUnit 의존성 규칙)"]
S2["전체적·촉발\n(통합 계약 검증)"]
S3["동적·연속\n(부하 시 응답시간)"]
end
CI --> STAGE
STAGE -->|모두 통과| DEPLOY["배포(카나리)"]
STAGE -->|위반| FAIL["머지 차단·알림"]
DEPLOY --> PROD["운영 환경"]
PROD -->|관측성 지표| MON["연속 피트니스 함수\n(가용성·지연 모니터링)"]
MON -.->|SLO 위반 경보| DEV
구체적으로 Java 진영에서는 ArchUnit으로 "..web.. 패키지는 ..persistence.. 패키지에 접근할 수 없다"를 JUnit 테스트로 작성해 매 PR마다 실행한다.
.NET의 NetArchTest, Python의 import-linter, JavaScript의 dependency-cruiser도 같은 역할을 한다.
이 테스트가 실패하면 머지가 차단되므로, 설계 규칙이 위키 문서가 아니라 빌드 실패라는 즉각적 신호로 강제된다.
이것이 2판이 특히 강조한 "아키텍처 거버넌스의 자동화(Automating Architectural Governance)"이며, 분기 1회 아키텍처 검토위원회(ARB)가 수백 건의 변경을 사후에 훑던 방식과 근본적으로 다르다.
4. 아키텍처 퀀텀과 적용 절차
진화형 아키텍처의 변경 단위를 논할 때 핵심 개념이 아키텍처 퀀텀(architectural quantum)이다. 퀀텀은 독립적으로 배포 가능하고 높은 기능적 응집을 가지며 정적·동적 결합이 완결된 최소 단위를 뜻한다. 퀀텀이 작고 경계가 뚜렷할수록 변경의 파급 범위가 좁아져 진화가 쉬워지고, 반대로 여러 서비스가 데이터베이스를 공유하는 등 결합이 얽히면 퀀텀이 거대해져 '분산 모놀리스'처럼 진화가 어려워진다. 따라서 진화 역량은 [[domain-driven-design]]의 경계 컨텍스트 정렬, 낮은 결합도 설계와 직접 연결되며, [[strangler-fig-pattern]]으로 레거시를 점진 대체하는 전략과 자연스럽게 맞물린다.
적용 절차는 통상 다음 순서를 따른다. ① 보전할 아키텍처 특성(품질 속성)을 이해관계자와 합의해 우선순위화한다 — 모든 특성을 지킬 수는 없으므로 '가장 중요한 몇 가지'를 고른다. ② 각 특성을 측정 가능한 임계값과 함께 피트니스 함수로 번역한다. ③ 피트니스 함수를 파이프라인·모니터링에 배치해 자동 실행한다. ④ 변경을 작은 단위로 만들고 배포하며, 위반 시 즉시 피드백을 받는다. ⑤ 운영 지표를 관찰해 임계값과 함수 자체를 주기적으로 재검토한다.
이 절차에서 자주 간과되는 것은 마지막 책임 순간(last responsible moment) 원칙과 과도한 피트니스 함수의 역설이다. 너무 이른 추상화는 변경을 어렵게 하므로 결정은 필요한 순간까지 미루되, 일단 중요한 특성이 정해지면 즉시 피트니스 함수로 못 박는다. 동시에 함수가 지나치게 많거나 임계값이 과하게 엄격하면 정상적 진화마저 막혀 '변경을 돕는 장치가 변경을 가로막는' 역설이 생긴다. 또한 Conway의 법칙에 따라 시스템 구조가 조직 구조를 닮는다는 점을 역이용해, 원하는 아키텍처에 맞게 팀을 먼저 배치하는 '역(逆) Conway 기동'을 병행하면 진화가 조직 차원에서 지지된다([[team-topologies]]).
5. 전통적 아키텍처 거버넌스와의 비교
진화형 접근의 가치는 전통적 거버넌스와 대비할 때 분명해진다. 단순 항목 나열이 아니라 '왜 차이가 생기는가'를 보면, 핵심은 검증의 시점·주체·형태가 다르다는 데 있다.
| 구분 | 전통적 거버넌스 | 진화형(피트니스 함수) |
|---|---|---|
| 검증 시점 | 분기·반기 사후 검토(ARB) | 매 커밋·배포·상시 |
| 검증 주체 | 아키텍트의 수동 리뷰 | 자동화된 실행 가능 검증 |
| 산출물 | 정적 설계 문서 | 살아 있는 실행 코드 |
| 피드백 지연 | 수 주~수 개월 | 수 분~실시간 |
| 변경 태도 | 변경 억제·동결 | 안전한 변경 촉진 |
전통적 모델에서 설계 문서는 작성 직후부터 코드와 어긋나기 시작한다. 분기 1회 검토로는 그 사이 수백~수천 건의 커밋이 만든 구조적 침식(technical erosion)을 따라잡을 수 없고, 위반을 발견해도 이미 깊이 얽혀 되돌리기 어렵다. 반면 피트니스 함수는 위반을 '발생 즉시' 빌드 실패로 드러내므로, 수정 비용이 수십 배 낮은 시점에 교정된다 — 결함 수정 비용이 단계가 늦어질수록 기하급수적으로 커진다는 품질공학의 오래된 경험칙과 정확히 부합한다. 이 차이가 [[technical-debt]]의 누적 속도를 좌우한다.
구체 사례로, 어느 글로벌 스트리밍 기업은 수백 개 마이크로서비스의 회복력 특성을 카오스 실험 기반 연속 피트니스 함수로 상시 검증해, 특정 인스턴스 장애가 전체로 번지지 않음을 배포 전부터 보장한다. 또 다른 사례로 대형 플랫폼 조직은 ArchUnit 규칙 수백 개를 CI에 심어 "허용되지 않은 계층 간 의존"을 머지 단계에서 차단함으로써, 분기 ARB가 사후에 적발하던 설계 위반을 사실상 0으로 수렴시켰다. 이들의 공통점은 아키텍처 특성을 '문서로 선언하고 사람이 지키는' 대상에서 '코드로 선언하고 파이프라인이 강제하는' 대상으로 옮겼다는 점이다.
6. 심화: 데이터·AI 시대의 피트니스 함수와 플랫폼화
최근 흐름은 피트니스 함수를 코드 구조를 넘어 데이터·ML·보안·운영 전 영역의 거버넌스 자동화로 확장하는 것이다. 데이터 영역에서는 스키마 레지스트리와 결합해 역호환을 깨는 스키마 변경을 차단하거나([[schema-registry]]), 데이터 계약([[data-contract]])의 준수 여부를 파이프라인에서 검증한다. ML 영역에서는 모델 드리프트([[model-drift-monitoring]])나 공정성·성능 지표가 임계값을 벗어나면 배포를 막는 'ML 피트니스 함수'가 MLOps 파이프라인에 들어가며, 생성형 AI에서는 환각률·독성·프롬프트 인젝션 방어율 같은 품질을 평가(eval) 게이트로 상시 측정하는 방식으로 진화형 사고가 확산되고 있다.
조직 차원에서는 플랫폼 엔지니어링([[platform-engineering]])이 피트니스 함수를 '골든 패스(golden path)'에 기본 탑재해 모든 팀이 공통 거버넌스를 자동으로 상속받게 한다. 정책 코드화([[policy-as-code]])·DORA 지표([[dora-metrics]])와 결합하면, 아키텍처 특성의 보전 여부와 전달 성과를 하나의 대시보드에서 관찰·개선할 수 있다. 이는 거버넌스를 '통제 비용'에서 '전달 속도를 높이는 역량'으로 재정의하는 전환이며, 생성형 AI가 코드 생산량을 급증시키는 환경에서 자동화된 아키텍처 검증의 중요성은 더욱 커진다.
다만 이러한 확장은 측정 가능성이라는 전제를 요구한다. '좋은 아키텍처'의 상당 부분은 가독성·이해 용이성처럼 자동 측정이 어려운 특성이어서, 모든 것을 피트니스 함수로 환원하려는 과욕은 오히려 왜곡을 낳는다. 따라서 자동화 가능한 특성과 인간 판단이 필요한 특성을 구분하고, 후자는 수동·시간형 함수와 설계 리뷰로 보완하는 균형이 핵심 과제로 남는다.
7. 고려사항 및 시사점
기술사 관점에서 진화형 아키텍처 도입은 기술·조직·거버넌스·비용의 트레이드오프를 함께 설계하는 문제다.
- 적용 전략(점진적 도입): 모든 특성을 한 번에 피트니스 함수로 만들려 하지 말고, 침식이 잦은 소수의 핵심 특성(계층 의존·순환 참조·핵심 SLO)부터 자동화하고 성숙도에 따라 확장한다. 레거시에는 [[strangler-fig-pattern]]과 결합해 대체 구간에만 먼저 함수를 적용하는 것이 현실적이다.
- 트레이드오프(민첩성 대 통제): 피트니스 함수가 많을수록 통제력은 커지나 변경 자유도와 빌드 시간이 희생된다. 함수 수와 임계값을 과도하게 조이면 진화를 돕는 장치가 진화를 막는 역설에 빠지므로, 실패율·빌드 시간을 지표로 두고 함수 포트폴리오 자체를 주기적으로 가지치기해야 한다.
- 조직·문화(역 Conway 기동): 자동 거버넌스는 "아키텍트가 문지기"라는 문화에서 "팀이 자율적으로 특성을 보전"하는 문화로의 전환을 전제한다. Conway의 법칙을 역이용해 팀 경계를 원하는 아키텍처 퀀텀에 맞추고, [[team-topologies]]의 스트림 정렬 팀이 자기 피트니스 함수를 소유하게 한다.
- 측정의 한계와 보완: 가독성·설계 적절성 등 비자동화 특성은 수동·시간형 함수와 리뷰로 보완하고, ATAM([[architecture-tradeoff-analysis-method]]) 같은 정성적 평가와 병행한다. 자동 측정만 맹신하면 '측정되는 것만 개선되는' 편향이 생긴다.
- 전망(거버넌스의 코드화): 데이터·ML·AI·보안으로 확장된 피트니스 함수는 플랫폼 엔지니어링·정책 코드화와 합류해 '거버넌스의 코드화'로 수렴한다. 생성형 AI가 코드 생산을 가속할수록, 변경을 안전하게 흡수하는 자동 검증 역량이 조직의 전달 속도와 품질을 동시에 결정하는 핵심 경쟁력이 될 것이다.
참고자료
- Building Evolutionary Architectures, 2nd Edition — Ch.2 Fitness Functions (O'Reilly): https://oreilly.com/library/view/building-evolutionary-architectures/9781492097532/ch02.html
- Building Evolutionary Architectures, 2nd Edition — Ch.4 Automating Architectural Governance (O'Reilly): https://oreilly.com/library/view/building-evolutionary-architectures/9781492097532/ch04.html
- Thoughtworks, Building Evolutionary Architectures (2nd Edition): https://www.thoughtworks.com/insights/books/building-evolutionaryarchitectures-second-edition
- InfoQ, Fitness Functions for Your Architecture: https://www.infoq.com/articles/fitness-functions-architecture/
한 줄 요약: 진화형 아키텍처는 보전할 품질 속성을 피트니스 함수라는 실행 가능한 검증으로 못 박아 매 변경마다 자동 평가함으로써, 여러 차원에 걸친 변경을 안전하고 점진적으로 흡수하도록 아키텍처 거버넌스를 사후 문서 검토에서 상시 자동화로 전환하는 접근이다.