선택 기준과 기본 용어
마이크로서비스는 애플리케이션을 작은 프로세스로 많이 나누는 기술이 아니라, 업무 능력을 맡은 서비스가 각자 배포되고 운영되는 구조입니다. 서비스는 보통 하나의 업무 능력과 그 능력을 해석하는 경계 문맥을 가집니다. 경계 문맥(bounded context)은 같은 단어가 같은 의미와 규칙을 갖는 업무 모델의 범위입니다. 예를 들어 주문의 상품 가격과 회계의 매출 금액은 숫자가 같아 보여도 변경 규칙과 책임이 다를 수 있습니다.
모놀리스는 하나의 배포 단위로 실행되는 애플리케이션입니다. 그 안에 모듈이 없다는 뜻은 아닙니다. 모듈러 모놀리스는 하나의 프로세스 안에서 모듈·포트·데이터 접근 권한을 분리해, 네트워크 비용 없이 강한 경계를 만드는 방식입니다. 마이크로서비스는 이 경계를 별도 프로세스와 배포 단위로 확장한 선택입니다.
따라서 첫 질문은 “몇 개의 서비스를 만들까?”가 아닙니다. “어떤 변경은 함께 확정되어야 하며, 어떤 책임은 독립적으로 운영되어야 하는가?”입니다. 분리하면 배포와 확장이 독립될 수 있지만, 네트워크 지연·부분 실패·계약 진화·관측·대사가 새 비용으로 들어옵니다. Microsoft Azure Architecture Center의 버전 독립적 개념 문서도 마이크로서비스가 단순한 분해를 넘어 설계·배포·운영 방식의 전환을 요구한다고 설명합니다.
비용 구조와 독립성
한 프로세스에서 주문과 재고를 같은 데이터베이스 트랜잭션으로 바꾸면, 커밋 성공은 두 변경의 원자적 결과를 함께 뜻할 수 있습니다. 프로세스를 나누면 각 데이터베이스의 로컬 트랜잭션은 여전히 강하지만, 두 커밋 전체를 하나의 업무 성공으로 만드는 비용이 생깁니다. 호출 중단, 응답 유실, 재시도, 보상, 사용자에게 보이는 중간 상태를 설계해야 합니다.
| 판단 축 | 모듈러 모놀리스 | 마이크로서비스 |
|---|---|---|
| 배포 | 하나의 단위, 내부 모듈 선택적 검증 | 서비스별 독립 배포 가능 |
| 데이터 | 같은 DB의 로컬 제약 활용 가능 | 서비스별 원본·쓰기 권위 필요 |
| 실패 | 프로세스 전체 영향 가능 | 네트워크·부분 실패 범위 증가 |
| 확장 | 프로세스 단위 확장 | 업무 능력별 확장 가능 |
| 운영 | 상대적으로 단순한 호출·관측 | 계약·추적·대사·복구 필요 |
독립 배포는 독립성의 증거 중 하나일 뿐입니다. 주문 서비스와 재고 서비스가 별도 이미지로 배포되더라도, 로그인 한 번에 연쇄 호출 열 번을 해야 하거나 모든 변경이 공통 라이브러리 배포를 기다리면 실제 결합은 남아 있습니다. 반대로 같은 프로세스 안에서 데이터 접근을 포트 뒤에 숨기고 공동 변경률을 측정하면, 아직 분리하지 않아도 미래 경계의 품질을 관찰할 수 있습니다.
업무 경계와 변경 결합도
서비스 후보는 테이블 이름이나 기술 계층이 아니라 업무 규칙에서 출발합니다. 한 서비스 안에서 함께 판단해야 하는 조건, 함께 바뀌는 코드, 같은 팀이 책임지는 운영 지표를 먼저 묶습니다. 한 업무 능력이 다른 경계의 내부 테이블을 자주 읽어야 한다면, 표면만 나눈 것일 수 있습니다.
다음 신호를 함께 기록하면 경계를 추측으로 정하지 않을 수 있습니다.
- 같은 규칙을 바꾸기 위해 여러 서비스가 매번 함께 배포되는가
- 한 요청이 서비스 사이를 여러 번 왕복하는가
- 한 팀이 원본 데이터와 장애 복구를 끝까지 책임질 수 있는가
- 보안·규제·확장 패턴이 다른가
- 한 기능의 부하나 장애가 다른 기능과 독립되어야 하는가
- 분리 뒤 보상과 대사가 업무적으로 감당 가능한가
호출이 지나치게 잦은 수다스러운 호출(chatty call)은 네트워크가 느리다는 단순한 문제가 아니라 경계가 잘못 잡혔다는 신호일 수 있습니다. 같은 Microsoft Azure Architecture Center 경계 지침은 기능을 나눈 결과 서비스 사이 호출이 지나치게 많아지면 같은 서비스에 속할 가능성을 검토하라고 설명합니다. 경계가 불확실하면 처음부터 더 거칠게 묶고, 실제 변경·부하·장애 자료가 쌓인 뒤 나누는 편이 되돌리기 쉽습니다.
모듈 경계와 프로세스 경계
처음 주문 시스템을 만들 때 Order, Inventory, Payment, Shipping 모듈을 한 프로세스에 둘 수 있습니다. 각 모듈은 공개 명령과 결과만 제공하고 상대 저장소를 직접 만지지 않습니다. 이때 공동 변경률과 트랜잭션 범위를 측정하면, 네트워크를 도입하기 전에 실제 결합을 볼 수 있습니다.
프로세스 분리는 다음 조건이 모였을 때 검토합니다.
- 업무 경계가 안정되어 모듈 간 내부 호출이 공개 계약으로 바뀔 수 있습니다.
- 원본 데이터의 쓰기 권위와 복구 책임을 한 팀이 맡을 수 있습니다.
- 호출 지연과 부분 실패를 포함한 사용자 계약을 정의할 수 있습니다.
- 배포·관측·보안·당직 운영을 감당할 능력이 있습니다.
- 독립 확장이나 별도 규제 같은 분리의 이득이 측정됩니다.
별도 데이터베이스를 먼저 만들고 기존 SQL을 계속 공유하는 방식은 이 조건을 만족하지 않습니다. 데이터베이스가 나뉘었어도 배포가 함께 일어나고, 한 장애가 공통 연결 풀과 공통 저장소를 고갈시키면 독립성은 명목에 그칩니다. 필요하면 두 서비스를 다시 하나의 모듈로 합치는 것도 설계 실패가 아니라 비용을 줄이는 정상적인 조정입니다.
그림을 글로 읽기
- 업무 능력·경계 문맥
- 공동 불변식·변경 결합
- 강한 모듈 경계
- 독립 서비스 경계
- 배포·지연·장애·복구 지표
- 업무 능력·경계 문맥 → 공동 불변식·변경 결합: 규칙 확인
- 공동 불변식·변경 결합 → 강한 모듈 경계: 함께 확정
- 공동 불변식·변경 결합 → 독립 서비스 경계: 독립 이득
- 강한 모듈 경계 → 배포·지연·장애·복구 지표: 기준선 관찰
- 독립 서비스 경계 → 배포·지연·장애·복구 지표: 분리 비용 비교
주문 흐름의 기준선
이제 작은 주문을 기준선으로 삼겠습니다. 고객이 o-17을 만들고, 재고를 예약하고, 결제를 승인한 뒤 배송을 생성하는 흐름입니다. 먼저 모듈러 모놀리스에서 주문·재고·결제·배송의 변경이 하나의 데이터베이스 거래에 들어간다고 가정합니다.
초기 상태는 다음과 같습니다.
주문 o-17: 없음
재고 SKU-A: available=1, reserved=0
결제: 없음
배송: 없음
한 거래가 성공하면 중간 상태가 외부에 보이기 전에 다음 결과를 얻습니다.
주문: ACCEPTED
재고 SKU-A: available=0, reserved=1
결제: AUTHORIZED
배송: CREATED
이 구조의 장점은 재고 예약 성공과 주문 생성이 같은 커밋으로 판단된다는 점입니다. 하지만 결제 제공자나 배송 시스템이 별도 외부 시스템이라면 같은 데이터베이스 거래에 넣을 수 없습니다. 결제 승인이 이미 외부에서 성공한 뒤 로컬 거래가 실패할 수 있으므로, 모놀리스라는 이름만으로 전체 원자성을 주장하면 안 됩니다.
마이크로서비스로 나누면 각 서비스의 성공을 다음처럼 기록할 수 있습니다.
| 시점 | Order | Inventory | Payment | Shipping |
|---|---|---|---|---|
| t0 | 없음 | available=1 | 없음 | 없음 |
| t1 | PENDING |
hold H-7 |
없음 | 없음 |
| t2 | PENDING |
held | AUTH_PENDING |
없음 |
| t3 | PENDING |
held | AUTHORIZED |
없음 |
| t4 | CONFIRMED |
held→confirmed | authorized | CREATED |
t2와 t3 같은 중간 상태는 버그가 아니라 분산 workflow의 사실입니다. 다만 각 상태의 만료 시간, 재시도, 사용자 표시, 실패 시 보상을 정해야 합니다. 재고 예약이 만료된 뒤 늦게 결제가 승인되면 주문을 과거 상태로 덮어쓰지 않고, 결제 확인·환불·재예약을 포함한 조정 경로로 보낼 수 있어야 합니다.
분리 판단의 수치화
팀이 “서비스 수가 많으면 확장된다”고 주장한다고 합시다. 먼저 지난 한 달의 변경 기록에서 주문과 재고가 함께 배포된 횟수를 세고, 트래픽에서 두 모듈 사이 왕복 수와 p99 지연을 측정합니다. 실제 수치는 조직과 workload마다 다르므로 여기서는 판단 절차만 제시합니다.
예를 들어 공동 변경 12건 중 9건이 두 모듈을 함께 수정했고, 주문 하나가 재고 조회를 6회 왕복하며, 재고 장애 때 주문 생성도 실패한다고 합시다. 이 자료는 “지금 경계가 독립적이지 않다”는 증거입니다. 반면 결제만 별도 규제 권한과 독립 확장 요구가 있고, 호출이 승인 1회로 안정되어 있다면 결제 경계를 먼저 분리할 근거가 생깁니다.
분리 전후에 같은 항목을 비교합니다.
- 공동 변경 비율과 함께 배포한 서비스 수
- 요청당 네트워크 왕복 수와 p99 지연
- 중간 상태·보상·수동 대사 건수
- 한 장애가 실패시키는 핵심 기능의 범위
- 서비스별 원본 데이터·복구·당직 담당자
이 수치들이 분리 뒤 악화되면 “이미 서비스이므로 유지”라고 결론 내리지 않습니다. 응집된 모듈로 다시 합치거나, 호출을 줄이는 읽기 모델을 두거나, 업무 불변식을 한 경계로 재배치할 수 있습니다.
구현과 운영의 시작점
구현은 프로세스 생성보다 모듈 계약에서 시작합니다. 각 모듈에 명령, 결과, 오류, 멱등 키, 소유 데이터, 외부 효과를 적습니다. 다른 모듈은 저장소를 직접 읽지 않고 포트나 공개 계약만 사용합니다. 이 계약이 안정되면 특정 모듈을 별도 프로세스로 옮길 때 네트워크와 재시도 정책을 추가할 수 있습니다.
운영에서는 독립 배포 성공만 보지 않습니다. 한 서비스가 느려졌을 때 핵심 주문이 어떤 상태로 남는지, 재시작 뒤 어떤 작업을 재개하는지, 사용자가 pending을 어떻게 이해하는지 확인합니다. 로그와 지표에는 주문 논리 ID, 서비스, 상태 버전, 호출 시도, 복구 담당자를 연결하되 결제수단 원문 같은 민감 정보를 복사하지 않습니다.
이 장의 기준선은 이후 주문 workflow에서 outbox·inbox·사가를 비교할 때 사용합니다. 모듈러 모놀리스가 언제나 더 낫다는 결론도, 마이크로서비스가 언제나 더 확장된다는 결론도 아닙니다. 변경 결합과 업무 비용을 관찰할 수 있는 경계를 먼저 만들고, 분리의 이유가 실제 자료로 드러날 때 프로세스 경계를 선택하는 것이 핵심입니다.
참고 자료와 검증 범위
- Microservices Architecture Style - Azure Architecture Center — 2026-09-17 확인. 버전 독립적 개념 문서이며 페이지 메타데이터상 2025-06-30 게시, 2026-08-06 갱신, 커밋
f69851e7c8b27ca6e8983e7b7d91d35e99423a73입니다. 독립 배포, 업무 능력과 경계 문맥, 서비스별 데이터 소유, 분산 복잡성 주장을 사용했습니다. - Identify microservice boundaries - Azure Architecture Center — 2026-09-17 확인. 버전 독립적 개념 문서이며 페이지 메타데이터상 2022-07-26 게시, 2025-10-30 갱신, 커밋
b1b7a994a589cf5a20729780d75e4f78ec7aec70입니다. 수다스러운 호출, 업무 경계, 거친 시작점에 관한 주장을 사용했습니다. - 본문은 실제 주문 서비스나 성능 시험을 실행한 결과가 아닙니다. 주문 상태와 수치는 설명을 위한 설계 예이며, 저장소에서 실제 서비스 성능·조직 생산성·무중단 배포를 검증하지 않았습니다.