Skip to content

13.4 아키텍처 결정과 평가 — 품질 목표 위에서 대안의 비용을 비교한다

아키텍처 스타일에는 순위가 없다. 같은 이벤트 기반 구조가 한 시스템에서는 장애 격리를 만들고 다른 시스템에서는 추적 불가능한 상태와 운영 부담을 만든다. 이 문서는 품질 속성 시나리오로 중요한 결정을 찾고, 전술과 구조 대안을 위험·민감점·트레이드오프 관점에서 평가한 뒤 ADR로 유효 조건을 기록하는 방법을 다룬다.

학습 목표

  • 아키텍처 결정과 국소 구현 결정을 영향·비용·되돌리기 가능성으로 구분한다.
  • 품질 속성 시나리오에서 필요한 전술과 구조 후보를 도출한다.
  • 대안을 같은 시나리오에서 위험·민감점·트레이드오프로 평가한다.
  • 결정의 맥락·대안·결과·재검토 조건을 ADR로 기록한다.

배경: 상자 그림이 아키텍처가 아닌 이유

“주문 서비스 → 메시지 브로커 → 결제 서비스”라는 그림은 구조를 보여 주지만 다음 질문에는 답하지 않는다.

  • 메시지가 저장되기 전에 API 성공을 반환하는가?
  • 같은 메시지가 두 번 전달되면 누가 중복을 제거하는가?
  • 결제 완료와 주문 상태가 다를 때 어느 기록을 신뢰하는가?
  • 브로커 장애 중 취소 요청의 응답시간과 유실 허용 범위는 무엇인가?
  • 스키마를 바꿀 때 생산자와 소비자를 동시에 배포해야 하는가?

아키텍처는 요소와 연결뿐 아니라 그 구조를 선택한 근거, 경계의 계약, 품질 속성에 미치는 영향까지 포함한다. 모든 중요한 선택이 아키텍처 결정인 것은 아니다. 보통 다음 특성이 강할수록 아키텍처적이다.

  • 여러 팀·모듈·품질 속성에 넓게 영향을 준다.
  • 데이터·배포·운영 모델을 오래 제약한다.
  • 바꾸는 비용과 전환 위험이 크다.
  • 초기에 잘못 선택했을 때 뒤늦게 발견하기 쉽다.

중요성은 맥락에 따라 달라진다. 내부 관리 도구에서 데이터베이스 제품 선택은 국소적일 수 있지만 초당 수십만 건을 장기간 보존하는 분석 시스템에서는 핵심 아키텍처 결정이다.

핵심 개념

품질 속성이 아키텍처를 움직인다

기능은 여러 구조에서 구현할 수 있다. 주문 취소 기능은 단일 프로세스, 계층형 모놀리스, 비동기 워커, 여러 서비스 모두에서 만들 수 있다. 대안을 갈라놓는 것은 대개 응답성, 가용성, 변경 용이성, 보안, 감사성과 같은 품질 속성이다.

그러나 속성 이름이 아니라 13.2의 구체적 시나리오가 필요하다.

text
QA-RESP-01
평상시 부하에서 단일 결제사가 30초 동안 응답하지 않을 때,
인증된 고객의 취소 요청 99.9%에 2초 이내 접수 상태를 반환하고
접수한 요청을 잃지 않는다.

QA-MOD-02
정상 개발 환경에서 결제사 한 곳을 추가할 때,
주문 정책과 기존 결제사 구현을 수정하지 않고 adapter와 계약 검증만 추가하며
한 팀이 5개 작업일 안에 완료한다.

QA-AUD-03
감사 담당자가 지난 환불 한 건을 조사할 때,
승인된 도구로 요청자·정책 판단·외부 결과·수동 변경 이력을
10분 안에 누락 없이 복원한다.

첫 시나리오는 외부 지연 격리와 내구성, 두 번째는 모듈 경계와 확장 지점, 세 번째는 변경 불가능한 감사 기록과 상관관계를 압박한다. 같은 구조가 세 목표를 동시에 최적화하지 못할 수 있다.

전술 — 품질 반응을 만드는 설계 수단

아키텍처 전술(tactic)은 특정 품질 속성의 반응을 제어하는 설계 결정이다. 스타일보다 작은 단위이며 여러 구조 안에서 조합할 수 있다.

품질 목표전술 예얻는 것지불하는 비용·새 실패
응답성timeout, 작업 분리, queue, cache긴 작업·외부 지연을 요청 경로에서 제거stale 데이터, queue 지연, 상태 복잡성
가용성redundancy, health check, failover, graceful degradation일부 실패 중 서비스 지속중복 비용, split-brain·오탐 전환 위험
변경 용이성정보 은닉, adapter, indirection, 독립 배포 경계변경 전파와 조정 범위 감소간접성, 계약·버전 관리 비용
보안인증·인가, 최소 권한, 격리, 감사공격 표면과 영향 제한지연, 운영 복잡성, 복구 절차 제약
무결성transaction, idempotency, validation, reconciliation중복·부분 실패에서 불변식 보호처리량·가용성 비용, 보상 로직
관찰 가능성correlation ID, 구조화 로그, trace, health model실패 구간과 결정 경로 복원저장·성능·개인정보 비용

전술 이름만 적으면 설계가 아니다. 적용 위치, 자원 예산, 실패 의미와 다른 전술과의 상호작용을 정해야 한다. 예를 들어 retry는 일시 실패를 숨길 수 있지만 deadline, backoff, 멱등성, 전체 시도 예산 없이 적용하면 장애 중 부하를 증폭한다.

스타일 — 제약의 묶음이지 제품 등급이 아니다

아키텍처 스타일은 요소·관계·허용 제약의 반복되는 구조다. 다음 비교는 선택표가 아니라 품질 가설을 세우는 출발점이다.

계층형 모놀리스

하나의 배포 단위 안에서 표현, 응용, 도메인, 인프라 의존 방향을 나눈다.

  • 장점: 로컬 호출과 트랜잭션이 단순하고 개발·테스트·배포의 고정 비용이 작다.
  • 비용: 모듈 경계를 도구가 강제하지 않으면 우회 의존이 쌓이고 전체 배포의 충돌 반경이 커진다.
  • 적합 신호: 팀과 운영 규모가 작고 강한 정합성, 빠른 전체 변경이 중요하다.
  • 경계 신호: 독립 확장·배포 필요가 반복되고 한 모듈 장애가 전체를 자주 위협한다.

모듈러 모놀리스

하나의 프로세스·배포 단위를 유지하면서 모듈별 데이터 소유권과 공개 계약을 강하게 제한한다.

  • 장점: 네트워크 분산 비용 없이 논리적 독립성과 향후 분리 옵션을 만든다.
  • 비용: 빌드·런타임·리뷰 규칙으로 경계를 지속적으로 검증해야 한다.
  • 적합 신호: 도메인 경계는 보이지만 독립 배포의 경제적 근거가 아직 약하다.
  • 경계 신호: 특정 모듈의 자원·배포·보안 격리 요구가 프로세스 경계로는 충족되지 않는다.

서비스 분리

독립 프로세스가 네트워크 계약으로 통신하고 데이터·배포·운영 책임을 나눈다.

  • 장점: 독립 배포·확장·실패 격리와 팀 자율성의 가능성을 얻는다.
  • 비용: 지연, 부분 실패, 계약 진화, 관찰, 데이터 정합성과 플랫폼 운영 비용이 생긴다.
  • 적합 신호: 독립 변화·확장·격리의 측정된 가치가 있고 이를 소유할 팀·운영 역량이 있다.
  • 경계 신호: 모든 변경이 동시 배포이고 데이터베이스와 릴리스가 사실상 공유된다.

이벤트 기반

생산자가 사건을 발행하고 소비자가 시간적으로 분리되어 반응한다.

  • 장점: 생산자와 후속 작업의 시간 결합을 줄이고 여러 반응을 독립 확장할 수 있다.
  • 비용: 중복·순서·지연·스키마 진화, end-to-end 추적과 일시적 불일치를 다뤄야 한다.
  • 적합 신호: 완료 사실에 여러 독립 반응이 있고 즉시 동기 결과가 필요하지 않다.
  • 경계 신호: 강한 즉시 일관성과 단순한 호출 흐름이 핵심인데 이벤트로 숨은 orchestration을 만든다.

이 스타일들은 배타적이지 않다. 모듈러 모놀리스 안에서 일부 후속 작업만 이벤트로 분리할 수 있고, 서비스 내부는 계층형일 수 있다. “마이크로서비스 대 모놀리스”라는 한 축으로 모든 결정을 압축하지 않는다.

대안은 같은 시나리오 위에서 비교한다

주문 취소 처리에 세 대안이 있다고 하자.

  • A: HTTP 요청 안에서 정책 검사와 결제 취소를 모두 동기 처리
  • B: 데이터베이스에 취소 요청을 기록하고 같은 프로세스의 worker가 비동기 처리
  • C: 취소 서비스가 이벤트를 발행하고 결제·물류 서비스가 독립 처리
평가 항목A 동기 처리B 내부 비동기C 분산 이벤트
QA-RESP-01 외부 지연 중 2초 접수외부 timeout에 직접 영향접수와 실행 분리접수와 소비 분리
요청 유실 방지응답 전 완료하면 단순기록과 worker 인계의 원자성 필요DB–broker 이중 쓰기 해결 필요
상태 이해·디버깅단일 흐름이라 쉬움queue·worker 관찰 필요여러 서비스 상관관계 필요
QA-MOD-02 결제사 추가adapter 경계가 있으면 가능adapter 경계가 있으면 가능서비스 계약·배포까지 영향 가능
독립 확장·격리낮음프로세스 내부에서 제한적높을 수 있음
운영 고정 비용낮음중간높음

현재 트래픽과 팀이 작고 독립 배포 요구가 없다면 B가 QA-RESP-01을 만족하는 최소 구조일 수 있다. C의 장점은 실제 독립 확장·소유 요구가 생길 때 가치가 커진다. 미래 가능성만으로 가장 복잡한 구조를 선점하지 않는다.

평가 — 설계가 틀릴 수 있는 지점을 먼저 찾는다

아키텍처 평가는 다이어그램을 승인하는 의식이 아니다. 구현 비용이 커지기 전에 품질 가설의 위험을 드러내는 활동이다. SEI의 Quality Attribute Workshop(QAW)은 아키텍처가 확정되기 전에 이해관계자와 중요한 품질 시나리오를 생성·우선순위화한다. Architecture Tradeoff Analysis Method(ATAM)는 제안된 아키텍처를 품질 목표에 비춰 위험·민감점·트레이드오프로 분석한다.

정식 ATAM은 훈련된 평가팀과 여러 날이 필요한 절차다. 일반 제품팀이 이름만 빌려 짧은 회의를 “ATAM 완료”라고 부르지 않는다. 이 챕터의 경량 평가는 핵심 분석 질문만 사용한다.

  1. 사업 목표와 결정에 영향받는 이해관계자를 확인한다.
  2. 품질 속성 시나리오를 생성하고 중요도와 난이도로 우선순위화한다.
  3. 후보 구조, 전술, 경계 계약과 가정을 설명한다.
  4. 우선 시나리오를 구조에 통과시키며 다음을 기록한다.
    • 위험(risk): 요구를 충족하지 못할 수 있는 근거 있는 우려
    • 비위험(non-risk): 현재 근거로 충분히 충족된 판단
    • 민감점(sensitivity point): 작은 값 변화가 품질 결과를 크게 바꾸는 결정
    • 트레이드오프(tradeoff point): 여러 품질 속성에 상반된 영향을 주는 결정
  5. 모르는 것을 실험·측정·프로토타입 과제로 바꾸고 결정 시한을 정한다.

위험·민감점·트레이드오프를 구분한다

비동기 취소 대안 B를 평가한 예다.

  • 위험: worker가 처리 전에 프로세스와 함께 사라지면 접수된 요청이 유실될 수 있다.
  • 완화/증거: 요청 상태를 같은 데이터베이스 트랜잭션에 기록하고 재시작 시 미처리 건을 스캔하는 프로토타입과 장애 주입으로 확인한다.
  • 민감점: worker concurrency와 결제사 rate limit의 비율은 queue 지연과 외부 차단을 크게 바꾼다.
  • 트레이드오프: batch 크기를 키우면 처리량은 늘지만 단일 요청 지연과 재처리 범위가 커진다.
  • 비위험: 결제사 adapter 계약이 기존 두 구현의 오류 의미를 동일하게 정규화함을 contract test로 확인했다.

“Kafka 운영이 어렵다”처럼 넓은 문장은 위험 항목으로 충분하지 않다. 어떤 시나리오에서 어떤 구조 특성이 어떤 실패를 만들며, 무엇으로 확인할지를 적는다.

불확실성에는 문서보다 증거를 배치한다

모든 질문을 회의로 해결할 수 없다.

불확실성적합한 증거
외부 결제사의 지연·rate limit 분포운영 지표와 샌드박스 부하 실험
DB와 queue 사이 요청 유실 가능성장애 주입 가능한 walking skeleton
결제사 추가 시 변경 범위두 번째 adapter 구현과 contract test
감사 담당자의 기록 복원 가능성실제 사례를 사용한 tabletop walkthrough
서비스 분리의 팀 독립성변경·배포 동시성 기록과 소유권 분석

프로토타입은 제품 구현이 아니라 특정 가정을 반증하는 실험이어야 한다. 성공 조건, 관찰 값과 폐기 범위를 먼저 정하지 않으면 우연히 만든 코드가 근거 없이 운영 구조가 된다.

ADR — 결론보다 유효 조건을 기록한다

Architecture Decision Record(ADR)는 하나의 중요한 결정과 그 근거를 짧게 보존한다. 기본 구조는 다음과 같다.

markdown
# ADR-004: 주문 취소를 내구성 있게 접수하고 비동기로 실행한다

## 상태
Accepted — 2026-07-12

## 맥락
- QA-RESP-01은 결제사 30초 지연 중 99.9% 요청에 2초 내 접수를 요구한다.
- 현재 팀은 주문과 결제를 함께 배포하며 독립 확장 요구가 없다.
- 취소 요청의 중복과 유실은 재무 손실을 만든다.

## 결정
주문 DB에 취소 요청을 주문 상태와 같은 트랜잭션으로 기록하고,
같은 애플리케이션의 worker가 미처리 요청을 비동기 실행한다.
모든 요청은 idempotency key와 명시적 상태를 가진다.

## 검토한 대안
1. 요청 안에서 결제 취소 완료까지 동기 대기
2. 별도 취소 서비스와 메시지 브로커

## 결과
- 긍정: 외부 지연과 API 응답을 분리하고 추가 인프라를 피한다.
- 부정: 일시적 중간 상태, worker 지연 감시와 재처리가 필요하다.
- 위험: DB polling 부하와 오래된 미처리 요청 누적.

## 재검토 조건
- 취소 backlog p99가 합의한 완료 시간 예산을 반복 초과한다.
- 결제 처리의 독립 배포·확장 또는 보안 격리가 필요해진다.
- DB polling 부하가 주문 처리 품질 목표를 침해한다.

ADR은 회의록이나 기술 홍보물이 아니다. 결정 하나를 다루고, 당시 알려진 사실과 제약, 실제 비교한 대안, 긍정·부정 결과를 남긴다. 나중에 결정이 바뀌면 과거 ADR을 지워 현재 상태로 고치지 않는다. 새 ADR이 이전 결정을 대체(supersede)하고 왜 유효 조건이 깨졌는지 연결한다.

상태 이름은 팀에 맞게 단순화할 수 있다.

text
Proposed → Accepted → Deprecated / Superseded
                  └→ Rejected (검토했지만 선택하지 않은 경우)

코드와 함께 버전 관리하면 검토 시점과 변경 연결이 쉬워진다. 그러나 모든 라이브러리 선택을 ADR로 만들면 중요한 결정을 찾기 어렵다. 넓은 영향, 비싼 되돌리기, 반복 논쟁, 중요한 품질 트레이드오프 중 하나가 있는 결정을 우선 기록한다.

실무 관점

유행하는 구조를 요구사항으로 만들지 않는다

“이벤트 기반이어야 한다”는 문장은 조직 표준 같은 실제 제약이 아니라면 해법이다. 비동기성, 독립 확장, 감사 가능한 사건 기록 중 무엇을 원하는지 분해해야 더 단순한 대안과 비교할 수 있다.

분산은 논리 경계를 대신하지 않는다

13.3의 소유권과 계약이 불명확한 상태에서 서비스로 분리하면 모호성이 네트워크 실패와 배포 조정 비용을 얻는다. 먼저 모듈 경계를 세우고 독립 배포·자원·보안 격리 가치가 있을 때 물리 경계를 선택한다.

평가를 합의 투표로 끝내지 않는다

다수결은 선호를 결정할 수 있지만 품질 가설을 검증하지 않는다. 반대 의견을 위험이나 반증 실험으로 바꾸고, 증거가 부족하면 가정과 결정 만료 조건을 남긴다.

되돌릴 수 있는 결정과 그렇지 않은 결정을 구분한다

작고 값싼 결정을 모두 완벽히 분석하면 학습 속도를 잃는다. 데이터 모델·외부 계약·보안 경계처럼 비싼 결정에는 더 많은 시나리오와 증거를 요구하고, 쉽게 바꿀 수 있는 내부 구현은 최소 근거로 실험한다. 가역성 자체도 마이그레이션·호환 계층을 설계해 높일 수 있다.

정리

  • 아키텍처는 큰 상자 그림이 아니라 시스템 품질을 좌우하고 변경 비용이 큰 결정과 계약이다.
  • 품질 속성 시나리오가 전술과 구조 대안을 비교할 공통 기준을 제공한다.
  • 스타일은 장점 묶음이 아니라 구조 제약과 함께 따라오는 비용·실패 모드다.
  • 경량 평가는 위험·민감점·트레이드오프와 모르는 가정을 증거 과제로 바꾼다.
  • ADR은 선택의 장점뿐 아니라 대안, 부정적 결과와 재검토 조건을 보존한다.

확인 문제

  1. 취소 API의 p99를 낮추기 위해 메시지 queue를 도입하자는 제안이 나왔다. 결정 전에 어떤 시나리오와 새 실패 모드를 확인해야 하는가?
  2. 두 서비스가 독립 배포 가능하지만 모든 기능 변경에서 동시에 배포된다. 어떤 아키텍처 가정을 다시 평가해야 하는가?
  3. ADR의 결정이 현재와 달라졌을 때 기존 ADR을 수정하지 않고 새 ADR로 대체해야 하는 이유는 무엇인가?
정답과 해설
  1. 자극·환경·응답시간·유실 허용 범위와 최종 완료 시간부터 명시한다. queue 내구성, DB–queue 이중 쓰기, 중복·순서, backlog, worker 장애, 관찰·재처리 비용을 평가해야 한다. API 응답만 빨라지고 최종 결과가 무기한 지연될 수 있다.
  2. 서비스 경계가 실제 변경축과 데이터 소유권을 반영하는지, 공유 계약·라이브러리·DB가 동시 배포를 강제하는지, 독립 배포가 해결하려던 품질 목표가 실제로 존재하는지 다시 본다. 논리 경계 또는 병합이 더 나을 수 있다.
  3. 과거 결정 당시의 맥락과 제약은 장애 분석과 현재 복잡성의 이유를 설명한다. 덮어쓰면 결정이 왜 합리적이었고 어떤 조건이 깨졌는지 잃는다. 새 ADR을 연결하면 결정의 수명 주기와 변화 근거를 추적할 수 있다.

참고 자료