마이크로서비스 경계를 어디에 그을까?
서비스를 잘게 나누기만 하면 정말 마이크로서비스가 되는 걸까. 많은 팀이 여기서부터 흔들린다. 기능별로 API를 분리하고 서버를 여러 개로 나눴는데도 운영은 더 복잡해지고 성능은 오히려 나빠지는 경우가 적지 않다. 실제로 문제의 시작은 “서비스를 몇 개로 나눌 것인가”보다 “어디를 하나의 책임으로 볼 것인가”에 있다.
마이크로서비스 아키텍처는 단순한 기술 분리가 아니다. 서비스 경계는 기술 스택보다 비즈니스 책임과 운영 독립성을 기준으로 결정된다. 단순히 작게 쪼개는 것이 아니라 독립적으로 변경·배포·운영 가능한 단위를 만드는 것이 핵심이다.
다만 모든 시스템이 반드시 마이크로서비스로 가야 하는 것은 아니다. 조직 규모가 작고 배포 빈도가 낮다면 오히려 모놀리식이 더 단순하고 효율적일 수 있다. 실제로 중요한 것은 시스템 규모보다 “변경 복잡도”다.
서비스 경계는 기능이 아니라 비즈니스 책임에서 시작된다
마이크로서비스를 처음 도입할 때 가장 흔한 실수는 화면이나 기능 기준으로 서비스를 나누는 것이다. 예를 들어 회원, 게시판, 댓글, 알림처럼 UI 기준으로 분리하면 처음에는 구조가 깔끔해 보인다. 하지만 시간이 지나면 서비스 간 의존성이 급격히 늘어난다.
특히 데이터 소유권이 불명확해지는 순간 문제가 커진다. 회원 서비스가 사용자 정보를 관리하는데 댓글 서비스와 주문 서비스도 동일한 데이터를 직접 참조하기 시작하면 변경 영향 범위가 커진다. 겉으로는 서비스가 분리돼 있어도 운영 방식은 다시 거대한 모놀리식처럼 변하기 쉽다.
이때 자주 등장하는 개념이 Bounded Context다. 이는 도메인 주도 설계에서 사용하는 개념으로, 하나의 서비스가 어떤 비즈니스 책임과 데이터를 독립적으로 관리하는지를 정의하는 경계다. 예를 들어 “주문”과 “결제”는 밀접하게 연결돼 있지만 변경 주기와 장애 영향 범위가 다르기 때문에 별도 컨텍스트로 분리되는 경우가 많다.
실제 현장에서는 기능보다 “업무 책임”을 기준으로 나누는 경우가 더 안정적으로 운영된다. 특히 조직 규모가 커질수록 팀 책임 범위와 서비스 경계가 일치해야 배포 충돌과 운영 병목이 줄어든다.
- 데이터 변경이 다른 서비스에 직접 영향을 주는가
- 독립 배포가 가능한가
- 장애 발생 시 영향 범위를 제한할 수 있는가
- 하나의 팀이 책임지고 운영 가능한 범위인가
좋은 서비스 경계를 판단하는 4가지 기준
좋은 마이크로서비스는 단순히 “작은 서비스”가 아니다. 독립성이 유지되는 서비스다. 실제 운영에서는 아래 네 가지 기준이 특히 중요하게 작동한다.
| 판단 기준 | 중요한 이유 |
|---|---|
| 데이터 소유권 | 서비스 간 강한 결합을 줄이기 위해 |
| 변경 주기 | 자주 수정되는 영역을 독립 배포하기 위해 |
| 장애 영향 범위 | 특정 장애가 전체 시스템으로 번지는 것을 막기 위해 |
| 팀 책임 범위 | 조직 단위와 서비스 운영 범위를 맞추기 위해 |
첫 번째는 데이터 소유권이다. 하나의 데이터는 가능하면 하나의 서비스가 책임져야 한다. 여러 서비스가 동일 DB를 직접 공유하기 시작하면 서비스 경계는 사실상 무너진다.
두 번째는 변경 주기다. 상품 추천 시스템처럼 자주 개선되는 영역과 정산 시스템처럼 안정성이 중요한 영역은 운영 방식이 다르다. 변경 속도가 다른 기능을 하나로 묶으면 배포 리스크가 커진다.
세 번째는 장애 전파 범위다. 알림 서비스 장애 때문에 주문 기능까지 멈춘다면 서비스 분리 효과가 거의 없다고 볼 수 있다. 장애가 국소적으로 머물 수 있도록 경계를 나누는 것이 중요하다.
- 서비스 간 직접 DB 접근 최소화
- 동기 호출 의존성 줄이기
- 독립 배포 가능한 구조 유지
- 장애 격리를 고려한 설계 적용
마지막은 팀 구조다. Conway’s Law처럼 조직 구조는 시스템 구조에 영향을 준다. 실제로 대규모 서비스 기업들은 팀 단위 책임 범위와 서비스 경계를 함께 설계한다.
반대로 조직 규모가 작은데 서비스를 과도하게 분리하면 운영 비용이 더 커질 수 있다. 팀은 하나인데 서비스만 여러 개로 늘어나면 배포·모니터링·장애 대응 비용이 빠르게 증가한다. 초기 스타트업에서 무리하게 MSA를 도입했다가 다시 단순한 구조로 돌아가는 이유도 여기에 있다.
너무 작게 나눈 마이크로서비스가 실패하는 이유
서비스를 지나치게 잘게 나누면 분산 시스템 비용이 빠르게 증가한다. 특히 “서비스는 작을수록 좋다”는 접근은 실무에서 자주 문제를 만든다.
대표적인 문제가 네트워크 호출 증가다. 하나의 요청을 처리하기 위해 여러 서비스를 연쇄 호출하면 응답 속도가 느려진다. 모놀리식에서는 함수 호출 한 번이면 끝나던 작업이 네트워크 통신으로 바뀌기 때문이다.
실제로 일부 조직은 사용자, 쿠폰, 포인트, 알림, 추천 기능을 모두 별도 서비스로 분리했다가 내부 API 호출 수가 급격히 증가하는 문제를 겪기도 했다. 주문 한 번 처리에 수십 번의 내부 호출이 발생하면서 병목이 생기고 장애 추적 난이도도 크게 올라간다.
분산 트랜잭션 역시 큰 문제다. 주문, 결제, 재고가 각각 독립 서비스로 나뉘면 데이터 정합성을 유지하기 어려워진다. 이때 Saga 패턴 같은 보상 트랜잭션 구조를 사용하기도 하지만 운영 난이도는 확실히 높아진다.
실무에서는 서비스 개수보다 “독립 운영 가능성”을 더 중요하게 본다. 실제로 지나치게 세분화된 마이크로서비스를 다시 통합하는 방향으로 구조를 수정하는 사례도 적지 않다. 서비스 수 자체가 목표가 되면 시스템 복잡도만 커질 가능성이 높다.

마이크로서비스 경계는 한 번 정하면 끝이 아니다
초기에 완벽한 서비스 경계를 만드는 경우는 드물다. 서비스 규모가 커지고 사용자 트래픽이 달라지면 경계 역시 계속 바뀐다.
처음에는 하나의 주문 서비스로 운영하던 구조가 이후에는 결제, 배송, 쿠폰, 정산으로 분리되기도 한다. 반대로 지나치게 잘게 나뉜 서비스를 다시 합치는 경우도 있다. 결국 서비스 경계는 고정된 설계가 아니라 운영 과정에서 계속 조정되는 구조에 가깝다.
그래서 중요한 것은 “현재 가장 합리적인 경계”를 만드는 일이다. 처음부터 완벽한 구조를 만들려 하기보다 변경 가능성을 열어두는 편이 현실적이다.
그리고 여기서 다음 문제가 시작된다. 서비스를 나누는 데 성공하더라도 성능 문제가 따라오기 때문이다. 네트워크 호출, 캐시 전략, API Gateway 병목, 분산 데이터 처리 같은 문제는 마이크로서비스 운영 단계에서 반드시 등장한다. 다음 글에서는 “마이크로서비스는 왜 느려지는가”를 중심으로 실제 성능 문제와 최적화 전략을 이어서 다룰 예정이다.