Architecture & Design/Software Architecture
Foundations - 08. 아키텍처 특성의 측정
"건강하다"는 말로는 병을 못 고친다 — 아키텍처 특성의 측정
건강검진을 받는다고 하자. 의사에게 "건강하세요?"라고 물으면 아무것도 진단할 수 없다. "네, 좀 피곤한데요"라는 대답으로는 혈압이 높은지, 콜레스테롤이 쌓였는지, 간 기능이 떨어졌는지 알 수 없다. 건강을 관리하려면 수치가 필요하다 — 혈압 120/80, 콜레스테롤 180, 간수치(GOT/GPT) 정상 범위. 수치가 있어야 추세를 보고, 개입 시점을 정하고, 치료가 효과가 있는지 판정한다.
소프트웨어 아키텍처도 같다. "이 시스템은 확장성이 좋아요", "유지보수성이 떨어져요" — 이런 정성적 판단으로는 아무것도 관리할 수 없다. 확장성이 "좋다"가 아니라 "피크 트래픽 3배 시 p99 500ms 유지"로 측정되어야, 개선했는지 퇴보했는지 판정할 수 있다. 측정하지 못하는 것은 관리하지 못한다.
이 비유의 한계: 건강검진은 보통 1년에 한 번 받는 단발성 검사지만, 아키텍처 특성은 지속적으로 관측해야 한다. 혈압은 검진 날만 재는 게 아니듯, 응답 시간·가동률·배포 빈도도 실시간으로 모니터링해야 의미가 있다.
정성의 한계 — 왜 숫자가 필요한가
품질 속성을 "빠르다", "안정적이다", "변경하기 쉽다"로만 서술하면, 그것을 다루는 도구가 없다. "빠르다"가 기준이면 언제까지 빨라야 하는가. 200ms인가 2초인가. 측정 기준이 없으면 토론이 끝나지 않고 — "충분히 빠른 것 같은데요" vs "아직 느려요" — 결국 가장 목소리 큰 사람이 이긴다.
Bass 등은 품질 속성을 시나리오로 구체화해야 한다고 본다(02번 글에서 다뤘다). 시나리오의 마지막 요소인 응답 측정(measure)이 바로 수치다 — "복구 시간 30초 이내", "가동률 99.95%", "초과 주문 0건". 이 수치가 있어야 개발이 끝났을 때 "요구사항을 충족했는가"를 판정할 수 있고, 운영 중에 "퇴보하고 있는가"를 감지할 수 있다.
세 가지 측정 축 — 구조적·운영적·전략적
건강검진에도 항목 분류가 있다 — 혈액검사(생체 지표), 영상 검사(구조), 기능 검사(운영). 아키텍처 특성도 측정하는 방식에 따라 세 축으로 나뉜다. Richards와 Ford가
| 축 | 무엇을 재는가 | 측정 방식 | 예 |
|---|---|---|---|
| 구조적(structural) | 코드·모듈의 정적 구조 | 정적 분석 도구 | 순환 복잡도(cyclomatic complexity), 의존성 화살표 수, 응집 지표(LCOM), 모듈 간 결합도 |
| 운영적(operational) | 런타임의 동적 동작 | 모니터링·부하 테스트 | p99 응답 시간, 가동률(uptime), 처리량(TPS), 에러율, 복구 시간(RTO) |
| 전략적(strategic) | 비즈니스에 미치는 영향 | 비즈니스 지표 | 출시 주기(deployment frequency), 변경 리드 타임, 장애당 매출 영향, 팀 생산성 |
구조적 특성은 코드를 열지 않고도 도구로 잴 수 있다 — 의존성 그래프에서 순환이 몇 개인지, 한 모듈에 몇 개의 클래스가 몰려 있는지. 운영적 특성은 시스템을 돌려봐야 나온다 — 부하 테스트로 p99를 재고, 모니터링으로 가동률을 추적한다. 전략적 특성은 비즈니스와 연결된다 — "배포가 일주일에 한 번인가, 하루 세 번인가"가 변경 민첩성의 척도다.
세 축이 따로 놀지 않는다. 구조적 문제(순환 의존, 낮은 응집)는 운영적 문제(배포 느림, 장애 전파)로 이어지고, 운영적 문제는 전략적 영향(출시 지연, 매출 손실)으로 번진다. 그래서 세 축을 함께 봐야 전체 그림이 나온다 — 혈액만 보고 건강을 판정하지 않듯, 코드 구조만 보고 아키텍처를 판정하지 않는다.
정량화와 trade-off 시각화
수치가 모이면 trade-off를 시각화할 수 있다. 가용성 99.95%를 위해 동기 복제를 쓰면 응답 시간이 50ms 늘어난다 — 이 관계를 수치로 보면, "가용성을 0.05% 올리기 위해 50ms를 희생할 것인가"라는 질문이 된다. "동기 복제가 느려요"가 아니라 "50ms 느려진다"로 말해야 토론이 끝난다.
가용성 99.9% → 99.95% 전환 시
응답 시간: 120ms → 170ms (+50ms, +42%)
복구 시간: 5분 → 30초 (개선)
비용: 복제 노드 1대 추가 (+월 $400)
이런 표를 놓고 "50ms 지연과 월 $400을 0.05% 가용성 향상과 교환할 것인가"를 결정하는 것이 아키텍처 작업이다. 수치가 없으면 이 토론 자체가 성립하지 않는다.
정성이 설 자리 — 수치가 전부는 아니다
수치화를 강조하다 보면 "모든 것을 잴 수 있다"는 오해로 빠지기 쉽다. 하지만 모든 것이 재지는 않는다. 코드의 "읽기 쉬움", 아키텍처의 "우아함", 팀의 "이해도" — 이런 것들은 수치로 환원하기 어렵다. 혈압이 정상이어도 환자가 "피곤하고 무기력하다"고 하면, 의사는 다른 검사를 시행한다. 수치가 정상이라고 환자가 건강한 것은 아니다.
그래서 정성적 판단은 버리는 게 아니라 보조 지표로 둔다. 코드 리뷰에서 "이 부분이 이해하기 어렵다"는 개발자의 체감은, 순환 복잡도가 정상 범위여도 발생할 수 있다. 신규 입사자가 "어디서부터 봐야 할지 모르겠다"고 하면, 그건 구조적 지표가 잡지 못한 문제의 신호다. 수치는 "어디를 의심해야 하는가"의 방향을 주고, 정성적 판단이 "실제로 문제인가"를 확인한다. 두 축이 함께 있어야 측정이 완전해진다.
설계 사례 — 세 축 지표를 대시보드로 구성하기
주문 시스템의 세 축(구조적·운영적·전략적) 지표를 실제로 어떻게 수집하고 대시보드에 띄우는지 본다. 측정이 단발 검사가 아니라 지속적 관측이 되려면, 코드에 지표 수집이 박혀 있어야 한다.
// 운영적 지표 — 런타임 측정 (Micrometer / Prometheus)
@Timed(value = "order.place", percentiles = {0.5, 0.99}) // p50, p99 응답 시간
public OrderPlaced place(Order order) {
// 주문 로직...
return event;
}
// Prometheus가 1분 단위로 scrape → Grafana 대시보드에 p99 추세 표시
// 구조적 지표 — 정적 분석 (CI 파이프라인에서)
// SonarQube / ArchUnit이 빌드 시 측정
@ArchTest
static final ArchRule 순환_의존_없음 = slices().matching("..(service).(*)")
.should().beFreeOfCycles();
// 순환 의존이 생기면 CI 실패 → 구조적 부채를 코드 변경 시점에 감지
// 전략적 지표 — 배포 빈도·변경 리드 타임 (DORA 메트릭)
// 배포 파이프라인(GitHub Actions)이 자동 기록
// 배포 횟수/주, PR 머지→배포 시간을 대시보드에 누적
세 축의 지표가 각자 다른 경로로 수집되어 하나의 대시보드로 모인다:
flowchart LR
Code["애플리케이션 코드"] -->|Micrometer| Prom["Prometheus<br/>(운영적 지표)"]
Code -->|CI 빌드| Sonar["SonarQube<br/>(구조적 지표)"]
Code -->|배포 파이프라인| Dora["DORA<br/>(전략적 지표)"]
Prom --> Dash["Grafana 대시보드"]
Sonar --> Dash
Dora --> Dash
이 세 축의 지표가 하나의 대시보드에서 만나면, "구조적 문제 → 운영적 문제 → 전략적 영향"의 인과가 보인다:
대시보드 예시 (Grafana)
┌──────────────────────────────────────────────┐
│ 구조적 (SonarQube) │
│ 순환 복잡도: 12 (임계치 10 초과 — 주의) │
│ 순환 의존: 1건 (order ↔ inventory) │
│ 커플링 지수: 0.7 (한 서비스가 3개에 의존) │
├──────────────────────────────────────────────┤
│ 운영적 (Prometheus) │
│ p99 응답: 1.2s (목표 500ms 초과 — 퇴보) │
│ 가동률: 99.91% (목표 99.95% 미달) │
│ 에러율: 0.3% (트래픽 피크 시 급증) │
├──────────────────────────────────────────────┤
│ 전략적 (DORA) │
│ 배포 빈도: 주 2회 (목표 일 1회 대비 지연) │
│ 변경 리드타임: 4일 (PR→배포, 목표 1일) │
│ 장애 복구: 45분 (목표 15분) │
└──────────────────────────────────────────────┘
이 대시보드가 시키는 것은 "어디를 봐야 하는가"다. 구조적 순환 의존(order ↔ inventory)이 운영적 p99 초과로 이어지고, 그 장애 복구 시간이 배포 빈도를 떨어뜨린다 — 세 축이 연쇄적으로 문제를 보여준다. 구조적 지표만 보면 "코드가 좀 복잡하군"으로 끝나지만, 운영적·전략적 지표와 나란히 보면 "그 복잡성이 고객 응답 시간과 배포 속도를 갉아먹고 있다"가 보인다.
수치가 추세로 쌓이면 "개선하고 있는가 퇴보하고 있는가"를 판정할 수 있다. p99가 500ms에서 1.2s로 점진적으로 올라간 추세를 보면, "어느 시점부터 퇴보가 시작됐나"를 찾을 수 있다 — 그 시점의 커밋·배포와 대조하면 원인을 특정할 수 있다. 단발 측정은 사진 한 장이고, 지속적 관측은 영상이다.
측정이 지속이어야 하는 이유
건강검진을 한 번 받고 "건강합니다" 도장을 찍었다고 해서, 그 후 1년을 아무것도 안 해도 건강한 게 아니다. 아키텍처도 마찬가지다. 한 번 측정하고 "p99 500ms 달성"으로 끝내면, 6개월 뒤 트래픽이 늘고 코드가 쌓여 500ms가 2초로 퇴보했을 때 아무도 모른다. 측정은 일회성 검사가 아니라 지속적 관측이어야 한다 — 모니터링 대시보드에 응답 시간·가동률·에러율을 띄워두고, 정기적으로 구조적 지표(복잡도, 결합도)를 재며, 추세를 본다.
수치가 추세로 쌓여야 "개선하고 있는가 퇴보하고 있는가"를 알 수 있다. 단발 측정은 사진 한 장이고, 지속적 관측은 영상이다 — 건강의 변화를 보려면 사진 한 장으로는 부족하다.
참고
- Richards, Ford —
(O'Reilly, 2020), Ch.3 (구조적·운영적·전략적 특성 분류) — 접근 2026-07-15 - Bass, Clements, Kazman —
(4th ed, Addison-Wesley, 2021), Ch.4 (품질 속성 시나리오와 측정) — 접근 2026-07-15
'Architecture & Design > Software Architecture' 카테고리의 다른 글
| Principles - 01. SOLID 원칙 (0) | 2026.07.15 |
|---|---|
| Foundations - 07. 빌드 vs 구매 vs 조달 (0) | 2026.07.15 |
| Foundations - 06. Conway's Law와 팀 토폴로지 (0) | 2026.07.15 |
| Foundations - 05. 기술 부채와 의사결정 (0) | 2026.07.15 |
| Foundations - 04. 아키텍처 문서화 (0) | 2026.07.15 |