마이크로서비스 아키텍처 · 서비스 경계와 도메인 · 이론
경계를 어디에 긋는가
한 줄 요약
경계는 명사가 아니라 언어에서 나온다. 같은 단어를 두 팀이 다른 뜻으로 쓰고 있다면 거기가 경계다.
왜 이게 필요했나
"주문 서비스, 상품 서비스, 회원 서비스로 나눕시다." 회의실에서 가장 흔히 나오는 문장이고, 가장 자주 실패하는 설계입니다. 이 방식은 데이터베이스 테이블 이름을 그대로 서비스 이름으로 승격시킨 것에 불과합니다. 결과는 예측 가능합니다. 주문 하나를 만들려면 상품 서비스와 회원 서비스를 각각 호출해야 하고, 세 서비스가 한 화면을 위해 항상 함께 움직입니다. 배포 독립성은 생기지 않습니다.
도메인 주도 설계가 제안하는 관점은 다릅니다. 경계는 데이터의 종류가 아니라 그 데이터를 두고 이야기하는 사람들의 언어에서 나옵니다.
어떻게 동작하나
같은 "상품"이라는 단어를 봅시다. 판매 팀에게 상품은 가격, 할인, 노출 여부입니다. 물류 팀에게 상품은 부피, 무게, 보관 온도입니다. 정산 팀에게 상품은 수수료율과 세금 코드입니다. 이 셋을 하나의 상품 테이블로 합치면, 물류 요구로 컬럼을 추가할 때마다 판매 팀 코드가 재배포됩니다.
이 지점이 바운디드 컨텍스트입니다. 각 컨텍스트는 자기만의 상품 모델을 가지고, 컨텍스트 사이는 식별자(예: SKU)로만 연결합니다. 컨텍스트 경계를 넘어갈 때 모델을 번역하는 것이 앞에서 본 부패 방지 계층입니다.
실무에서 경계 후보를 찾는 방법은 세 가지입니다. 첫째, 같은 단어의 뜻이 갈리는 지점. 둘째, 트랜잭션이 실제로 필요한 범위 — 한 트랜잭션 안에 있어야만 하는 데이터는 한 서비스 안에 있어야 합니다. 셋째, 변경 빈도 — 매주 바뀌는 부분과 1년에 한 번 바뀌는 부분은 다른 서비스일 가능성이 큽니다.
현장에서 만나는 모습
경계가 잘못됐다는 신호는 코드가 아니라 회의에서 먼저 나타납니다. 한 기능을 배포하는 데 항상 두 팀의 일정 조율이 필요하다면 경계가 틀린 것입니다. 그리고 정정하는 방법은 서비스를 더 쪼개는 게 아니라 대개 두 서비스를 도로 합치는 것입니다. 합치는 결정은 쪼개는 결정보다 훨씬 적게 내려지지만, 훨씬 자주 옳습니다.
또 하나. 마이크로서비스에서 "공용 라이브러리"는 조용한 결합입니다. 공통 DTO 를 한 저장소에 두면, 그 저장소의 버전을 올릴 때 모든 서비스가 함께 움직여야 합니다. 계약은 코드 공유가 아니라 스키마 문서(OpenAPI, protobuf)로 공유하는 편이 안전합니다.
다음 퀴즈에서 확인할 것
이 모듈은 개념만 다룹니다. 바로 이어지는 퀴즈로 경계 판단 기준을 점검하고, 다음 모듈에서 그렇게 나눈 서비스들이 실제로 통신할 때 무엇을 지불하는지를 손으로 확인합니다.