주문, 결제, 알림이 전부 들어있는 서버 하나로 서비스를 운영 중인데, 코드가 커지면서 작은 수정 하나에도 전체를 다시 배포해야 한다. 팀에서 "이제 마이크로서비스로 쪼개야 하지 않나"는 얘기가 나오기 시작했다.
언제: 팀이 한두 개고 트래픽이 단순 수평 확장으로 감당되는 동안. 패키지 경계만 처음부터 깔끔하게 지키면, 나중에 쪼갤 때도 그 경계선을 따라 자르면 된다.
비용: 배포가 한 덩어리라 한 모듈의 장애나 핫픽스가 전체 배포를 막을 수 있고, 알림처럼 부하가 튀는 모듈 하나 때문에 서버 전체를 같이 늘려야 한다.
언제: 특정 모듈의 부하 패턴이 나머지와 완전히 다르거나, 두 팀이 같은 배포 때문에 서로를 막기 시작할 때. 전체를 한 번에 쪼개지 않고 아픈 모듈 하나만 떼어낸다.
비용: 함수 호출이 네트워크 호출로 바뀌면서 부분 실패, 재시도, 데이터 정합성 문제가 따라온다. 모니터링과 배포 파이프라인 운영 비용도 서비스 수만큼 늘어난다.
기본은 모놀리스로 시작하되, 모듈 경계는 첫날부터 지킨다. 분리는 다이어그램이 멋있어서가 아니라 측정되는 고통이 생겼을 때 한다. 구체적으로는 두 팀이 한 배포에 주기적으로 막히거나, 한 모듈의 스케일 요구가 나머지와 확연히 달라지는 순간, 그 모듈 하나만 떼어낸다.
- 두 팀 이상이 서로의 배포 때문에 막히는 일이 주 1회 이상 반복된다
- 알림 같은 한 모듈의 트래픽 때문에 전체 인스턴스를 2배로 늘려야 한다
- p99가 500ms를 넘는데 원인이 한 모듈의 큐 적체(깊이가 계속 증가)로 좁혀진다
- 빌드+배포가 30분을 넘어 한 줄짜리 핫픽스에도 한 시간이 걸린다
🔧Grafana/Prometheus (p99, queue depth dashboards)k6 load test per module endpointArchUnit / Spring Modulith (enforce module boundaries)deploy pipeline metrics (lead time, blocked deploys)feature flags for strangler extraction
“I default to a modular monolith, and only split a service once two teams are actually blocked on one deploy.”
checking microphone…