[TIL] 아키텍처 특성은 어디까지 적용되어야 할까 (7장)

2026. 08. 30.Yeji Kim
Architecture

4장에서는 아키텍처 특성이 무엇인지, 5장에서는 어떤 특성이 중요한지 찾아내는 방법, 6장에서는 그 특성을 어떻게 측정하고 지속적으로 지킬지를 정리했다.

그런데 여기서 또 하나의 질문이 생긴다.

text
우리 시스템에서 Availability가 중요하다.

좋다.

그런데 어디까지 중요하다는 걸까?

text
시스템 전체?
 
결제 기능만?
 
특정 서비스만?
 
그 서비스가 사용하는 DB까지?
 
같이 호출하는 다른 서비스도?

예전에는 아키텍처 특성을 이야기할 때 자연스럽게 시스템 전체의 특성이라고 생각하는 경우가 많았다.

하지만 마이크로서비스처럼 시스템이 여러 독립적인 단위로 나뉘기 시작하면서 이 전제가 깨졌다. 현대적인 시스템에서는 서비스마다 필요한 아키텍처 특성이 다를 수 있기 때문이다.

7장은 결국 이 질문을 다룬다.

아키텍처 특성은 시스템의 어느 범위까지 적용되어야 하는가?


모든 부분이 똑같은 특성을 가질 필요는 없다

쇼핑몰을 하나 생각해보자.

text
상품 검색
주문
결제
추천
리뷰
관리자 페이지

이 모든 기능이 하나의 서비스 안에 있지만, 실제 중요도는 전혀 다르다.

상품 검색

text
Performance
Scalability
Availability

사용자가 많아도 빨리 검색할 수 있어야 한다.

결제

text
Security
Reliability
Data Integrity
Availability

요청을 잃거나 중복으로 결제하면 큰 문제가 된다.

추천

text
Performance
Scalability

추천이 잠깐 실패하더라도 결제까지 막힐 필요는 없을 수 있다.

관리자 페이지

text
Maintainability
Security
Simplicity

동시 사용자 수가 많지 않다면 엄청난 확장성은 필요하지 않을 수 있다.

즉 같은 시스템이라고 해서

text
System
 
Performance
Scalability
Availability
Security
Reliability
...

를 모든 부분에 똑같이 요구하는 것은 오히려 비효율적이다.


범위를 크게 잡으면 비용도 같이 커진다

예를 들어

text
우리 쇼핑몰은 99.999%의 Availability를 보장한다.

라고 결정했다고 해보자.

이걸 시스템 전체에 적용한다면

text
상품 검색
결제
추천
리뷰
관리자 페이지

전부 높은 가용성을 가져야 한다.

그러면 모든 영역에

text
서버 이중화
DB 이중화
자동 Failover
장애 감지
복구 체계

가 필요할 수 있다.

당연히 비용과 복잡성이 크게 올라간다.

하지만 실제 비즈니스 요구사항이

text
결제와 주문은 절대 중단되면 안 된다.
 
추천 서비스는 잠깐 내려가도 괜찮다.

라면?

전체 시스템을 동일한 수준으로 만드는 것은 과도한 설계일 수 있다.

차라리

text
Order / Payment
→ Availability 99.999%
 
Recommendation
→ Availability 99.9%

처럼 특성의 범위를 좁히는 것이 훨씬 현실적이다.


그래서 나온 개념이 Architecture Quantum

7장에서 중요한 개념이 Architecture Quantum, 즉 아키텍처 퀀텀이다.

조금 거칠게 표현하면,

하나의 일관된 아키텍처 특성을 공유하며 독립적으로 동작할 수 있는 아키텍처의 최소 단위

정도로 이해할 수 있다.

예를 들어 모놀리스 애플리케이션이 있다고 하자.

text
             Application
                  ↓
              Database

애플리케이션 전체가 하나의 프로세스로 배포되고 하나의 DB를 사용한다면 많은 아키텍처 특성을 함께 공유한다.

text
같이 배포되고
 
같이 확장되고
 
같이 장애가 발생하고
 
같은 DB에 영향을 받는다.

이런 경우 전체 애플리케이션이 하나의 큰 Architecture Quantum처럼 동작할 수 있다.


마이크로서비스에서는 범위가 훨씬 작아진다

반대로 시스템이 이렇게 구성되어 있다고 해보자.

text
Product Service ─── Product DB
 
Order Service ───── Order DB
 
Payment Service ─── Payment DB
 
Review Service ──── Review DB

각 서비스가

text
독립적으로 배포 가능하고
 
독립적으로 확장할 수 있고
 
자기 데이터베이스를 가지고 있고
 
장애도 어느 정도 격리되어 있다.

면 각 서비스마다 다른 아키텍처 특성을 적용할 수 있다.

예를 들어

text
Product Service
→ Scalability
→ Performance
 
Payment Service
→ Security
→ Reliability
→ Availability
 
Review Service
→ Maintainability
→ Availability

처럼 가져갈 수 있다.

즉 마이크로서비스 아키텍처에서는 아키텍처 특성의 범위를 서비스 단위까지 좁힐 수 있다.


하지만 서비스를 나눴다고 무조건 독립적인 것은 아니다

여기서 중요한 함정이 하나 있다.

서비스를 여러 개 만들었다고 해서 자동으로 Architecture Quantum이 여러 개 생기는 것은 아니다.

예를 들어

text
Order Service
      ↓
Shared Database
      ↑
Payment Service

처럼 두 서비스가 같은 데이터베이스를 공유한다고 해보자.

코드는 따로 있고 배포도 따로 할 수 있다.

하지만 데이터베이스가 장애 나면?

text
Order Service  DOWN
 
Payment Service DOWN

둘 다 영향을 받는다.

DB의 성능이 느려지면?

text
Order 느려짐
 
Payment 느려짐

둘 다 영향을 받는다.

즉 두 서비스가 Availability, Performance, Scalability 같은 특성을 완전히 독립적으로 가지기 어렵다.

코드를 나눴다고 아키텍처가 완전히 분리되는 것은 아니다.

데이터와 인프라의 결합도 함께 봐야 한다.


Architecture Quantum을 결정하는 세 가지 관점

Architecture Quantum을 이해할 때 크게 세 가지를 같이 보면 편하다.

text
Structural Coupling
Functional Cohesion
Synchronous Communication

하나씩 보자.


1. Structural Coupling

첫 번째는 구조적으로 얼마나 묶여 있는가다.

대표적인 것이 데이터베이스다.

text
Service A ──┐
            ├── Shared DB
Service B ──┘

두 서비스가 같은 데이터베이스를 공유하면 데이터 구조의 변경이 서로에게 영향을 미칠 수 있다.

예를 들어 Service A가 테이블을 변경했는데 Service B가 그 테이블을 직접 참조하고 있다면

text
Service A의 변경
      ↓
Database Schema 변경
      ↓
Service B 영향

이 된다.

겉으로는 서비스가 나뉘어 있지만 구조적으로는 강하게 결합되어 있다.

반대로

text
Service A → DB A
 
Service B → DB B

처럼 데이터까지 분리되어 있다면 훨씬 독립적으로 진화할 수 있다.


2. Functional Cohesion

두 번째는 기능적으로 하나의 목적을 이루는가다.

예를 들어 결제 시스템 내부에

text
Payment
Fraud Detection
Payment History

가 있다고 하자.

코드상으로는 여러 컴포넌트일 수 있지만, 비즈니스 관점에서는 하나의 결제라는 목적을 수행한다.

그래서 Architecture Quantum을 단순히

text
프로세스 하나 = Quantum 하나

라고 생각하면 안 된다.

중요한 건

하나의 비즈니스 기능을 제공하기 위해 어떤 컴포넌트들이 함께 움직이는가

다.


3. Synchronous Communication

2판에서 특히 강조되는 부분 중 하나가 동기 통신이다.

예를 들어 주문 요청이 이렇게 동작한다고 하자.

text
Client
  ↓
Order Service
  ↓ HTTP
Payment Service
  ↓ HTTP
Inventory Service

Order Service 자체는 멀쩡하다.

그런데 Payment Service가 죽으면?

text
Order 요청 실패

Inventory Service가 느려지면?

text
Order도 느려짐

즉 동기 호출에서는 호출하는 서비스의 특성이 호출받는 서비스에 강하게 영향을 받는다.

text
Order Availability
        ↓ depends on
Payment Availability
        ↓ depends on
Inventory Availability

서비스가 물리적으로 나뉘어 있어도 운영상의 특성은 묶일 수 있다.


동기 호출은 Availability도 묶는다

이걸 숫자로 보면 더 재밌다.

예를 들어

text
Order Service      99.9%
 
Payment Service    99.9%
 
Inventory Service  99.9%

라고 해보자.

Order 요청이 성공하려면 세 서비스가 모두 정상이어야 한다.

대략적으로 보면 전체 성공 가능성은

text
0.999 × 0.999 × 0.999
 
≈ 99.7%

가 된다.

각 서비스가 99.9% 가용성을 가지고 있어도, 여러 서비스를 동기적으로 연결하면 사용자 관점의 전체 가용성은 낮아질 수 있다.

그래서

분산했다고 해서 가용성이 자동으로 높아지는 것은 아니다.

오히려 동기 의존성이 늘어나면 전체 시스템의 가용성을 낮출 수도 있다.


비동기 통신은 특성의 범위를 분리할 수 있다

반대로 이벤트 기반으로 바꿔보자.

text
Order Service
      ↓
    Queue
      ↓
Payment Service

Order Service는 요청을 메시지 큐에 넣고 먼저 처리를 끝낼 수 있다.

Payment Service가 잠깐 내려가더라도

text
Queue에 이벤트 유지
 
↓
 
Payment Service 복구
 
↓
 
나중에 처리

할 수 있다.

이 경우 두 서비스의 Availability가 덜 강하게 묶인다.

text
Order Service
     ↓
Queue
 
----------------
 
Payment Service

즉 비동기 통신은 Architecture Quantum의 경계를 분리하는 수단이 될 수 있다.

물론 대신

text
Eventual Consistency
 
메시지 중복
 
순서 보장
 
재처리
 
관찰 가능성

같은 다른 복잡성이 생긴다.

역시 공짜는 없다.


범위는 아키텍처 스타일과 연결된다

여기서 7장의 내용이 이후 아키텍처 스타일 이야기와 연결된다.

예를 들어 레이어드 모놀리스는 보통

text
Presentation
Business
Persistence
Database

전체가 하나의 배포 단위다.

따라서 아키텍처 특성의 범위도 상대적으로 크다.

text
Architecture Quantum
┌───────────────────────┐
│ Presentation          │
│ Business              │
│ Persistence           │
│ Database              │
└───────────────────────┘

반면 마이크로서비스는

text
┌──────────────┐
│ Product      │
│ Product DB   │
└──────────────┘
 
┌──────────────┐
│ Order        │
│ Order DB     │
└──────────────┘
 
┌──────────────┐
│ Payment      │
│ Payment DB   │
└──────────────┘

처럼 여러 개의 Quantum을 가질 수 있다.

그래서 서비스별로

text
독립적인 Scalability
 
독립적인 Deployability
 
서로 다른 Availability 수준
 
서로 다른 Security 요구사항

을 적용하기 쉽다.

책에서도 아키텍처 특성의 범위는 적절한 아키텍처 스타일을 결정하는 데 중요한 기준이 된다고 설명한다.


그래서 "마이크로서비스는 확장성이 좋다"는 말도 조금 더 정확히 봐야 한다

흔히

text
마이크로서비스
→ Scalability 좋음

이라고 말한다.

그런데 정확히는

시스템의 각 부분을 서로 다른 수준으로 확장할 수 있다

는 점이 중요하다.

예를 들어

text
Product Search
→ 서버 100대
 
Payment
→ 서버 20대
 
Admin
→ 서버 2대

처럼 필요한 곳만 확장할 수 있다.

모놀리스라면

text
Product
Payment
Admin
 
      ↓
 
하나의 Application

이므로 상품 검색 때문에 트래픽이 늘어나도 전체 애플리케이션을 함께 확장해야 할 수 있다.

즉 분산 아키텍처가 제공하는 중요한 장점 중 하나는

아키텍처 특성의 범위를 좁혀서 필요한 부분에만 적용할 수 있다는 것

이다.


Cloud에서도 같은 문제가 생긴다

클라우드라고 해서 무조건 모든 특성을 쉽게 얻는 것은 아니다.

예를 들어 어떤 컴포넌트만 트래픽이 크게 증가한다고 해보자.

text
Image Processing
 
CPU 사용량 폭증

이 기능이 독립적인 Quantum이라면

text
Image Processing만 Auto Scaling

하면 된다.

하지만 거대한 모놀리스 안에 묶여 있다면

text
Image Processing
Order
User
Admin
Payment
 
↓ 전부 하나
 
Application 전체 Auto Scaling

을 해야 할 수도 있다.

즉 클라우드의 Elasticity 같은 특성을 얼마나 효과적으로 사용할 수 있는지도 아키텍처 특성의 범위와 시스템 경계에 영향을 받는다.


결국 범위를 좁힐수록 무조건 좋은 걸까?

그렇다면 모든 기능을 최대한 잘게 나누면 되지 않을까?

text
서비스 하나
 
↓
 
더 작은 서비스
 
↓
 
더 작은 서비스
 
↓
 
엄청 작은 서비스

하지만 당연히 문제가 생긴다.

서비스를 잘게 쪼갤수록

text
Network Calls ↑
 
Deployment Units ↑
 
Monitoring Complexity ↑
 
Distributed Transactions ↑
 
Operational Complexity ↑

가 된다.

즉 Architecture Quantum이 작아지면

text
독립적인 확장
 
독립적인 배포
 
장애 격리
 
특성별 최적화

는 좋아질 수 있지만,

대신

text
분산 시스템 복잡성
 
네트워크 비용
 
데이터 일관성 문제
 
운영 비용

을 감수해야 한다.

결국 여기서도 핵심은 트레이드오프다.


범위를 생각한다는 건 "이 특성을 누가 공유하는가?"를 묻는 것 같다

예를 들어 Availability가 중요하다고 판단했다고 해보자.

6장까지라면 이렇게 생각했다.

text
Availability가 중요하다.
 
↓
 
99.99%라는 기준을 정한다.
 
↓
 
측정하고 Fitness Function으로 관리한다.

7장에서는 질문 하나가 추가된다.

text
그런데 누구의 Availability가 99.99%여야 하지?
text
전체 시스템?
 
결제 서비스?
 
결제 서비스 + DB?
 
결제 서비스 + DB + 동기 호출하는 다른 서비스?

이 질문을 하지 않으면 특성을 정확하게 설계하기 어렵다.


프론트엔드에서도 비슷하게 생각할 수 있다

이 개념을 프론트엔드에 가져오면 조금 더 익숙하게 느껴진다.

거대한 SPA 하나가 있다고 해보자.

text
Editor
Dashboard
Admin
Billing

전부 하나의 bundle과 하나의 배포 단위로 묶여 있다.

Editor 때문에 고성능 그래픽 라이브러리가 필요해서 bundle이 커진다면

text
Admin
Billing
Dashboard

사용자도 그 비용을 같이 부담할 수 있다.

반대로 경계를 나눠

text
Editor App
 
Admin App
 
Billing App

처럼 가져간다면 각각 다른 특성을 최적화할 수 있다.

text
Editor
→ Runtime Performance
→ GPU / Rendering Performance
 
Admin
→ Maintainability
→ Simplicity
 
Billing
→ Security
→ Reliability

즉 프론트엔드에서도

어떤 품질 특성을 애플리케이션 전체가 공유해야 하고, 어떤 특성은 특정 영역에만 필요한가?

라는 질문을 할 수 있다.

Micro Frontend까지 가지 않더라도 bundle boundary, worker 분리, 패키지 경계 같은 설계에서도 비슷한 사고를 적용할 수 있다.


결국 7장은 "아키텍처 특성에도 경계가 있다"는 이야기 같다

4장부터 연결해보면 흐름이 꽤 재밌다.

text
4장
 
아키텍처 특성이 무엇인가?
        ↓
 
5장
 
우리 시스템에서
어떤 특성이 중요한가?
        ↓
 
6장
 
그 특성을 어떻게
측정하고 지속적으로 지킬까?
        ↓
 
7장
 
그런데 그 특성을
어디까지 적용해야 할까?

예전에는

text
우리 시스템의 Scalability
우리 시스템의 Availability

처럼 시스템 전체를 하나의 단위로 생각하기 쉬웠다.

하지만 현대적인 아키텍처에서는

text
어떤 컴포넌트가
 
어떤 데이터와 묶여 있고
 
어떤 서비스를 동기적으로 호출하며
 
어떤 아키텍처 특성을 함께 공유하는가

까지 생각해야 한다.


결국 아키텍처 특성의 범위란

한 줄로 정리하면,

아키텍처 특성이 적용되는 경계를 찾고, 같은 특성을 공유해야 하는 구성 요소들을 하나의 단위로 바라보는 것이다.

그리고 시스템을 볼 때

text
"우리 시스템은 확장성이 중요하다."

에서 끝나는 게 아니라

text
어느 부분이 확장되어야 하지?
 
다른 부분도 같이 확장되어야 하나?
 
이 서비스가 사용하는 DB는 독립적인가?
 
동기 호출하는 서비스가 죽으면 같이 죽는가?
 
이 특성을 더 작은 범위로 격리할 수 있는가?
 
범위를 분리했을 때 생기는 복잡성은 감당할 만한가?

를 같이 물어봐야 한다.

결국 7장을 읽고 나면 서비스를 나눈다는 것의 의미가 단순한 코드 분리가 아니라는 것이 조금 더 명확해진다.

좋은 경계란 단순히 기능을 예쁘게 나누는 경계가 아니라,

서로 다른 아키텍처 특성을 독립적으로 가질 수 있게 만들어주는 경계

이기도 한 것 같다.

그리고 이걸 판단하기 위한 단위가 바로 Architecture Quantum인 듯.


레퍼런스

  • Mark Richards, Neal Ford, Fundamentals of Software Architecture, 2nd Edition — Chapter 7, The Scope of Architectural Characteristics