TL;DR

  • 모놀리식은 하나의 코드베이스·배포 단위, MSA는 독립 서비스 단위로 분리하는 아키텍처
  • MSA 운영에는 API Gateway, 서비스 메시, 분산 추적, Kubernetes 오케스트레이터가 사실상 필수
  • 전환은 Strangler Fig 패턴으로 점진적 진행, 분산 환경 고유의 Saga·Eventual Consistency 문제 존재

1. 개요

현대 소프트웨어는 서비스 규모와 비즈니스 요구에 따라 다양한 아키텍처 스타일을 채택한다. 그 중 가장 널리 논의되는 두 가지는 Monolithic(모놀리식, 단일체) 아키텍처와 Microservice(마이크로서비스) 아키텍처다.

본 글에서는 두 아키텍처의 정의, 특징, 장단점, 대표 사례와 실제 선택 기준까지 정리한다.


2. Monolithic Architecture (모놀리식 아키텍처)

정의
  • “Monolith” = 하나의 큰 돌(덩어리)
  • 소프트웨어의 모든 기능을 하나의 코드베이스, 하나의 배포 단위로 구현하는 방식
  • 초기 웹서비스/앱 개발에서 가장 흔한 패턴
주요 특징
  • 단일 코드베이스: 모든 기능(인증, DB, API, UI 등)이 한 프로젝트/서버에 있음
  • 하나의 배포: 전체 앱이 한 번에 빌드·배포됨
  • 내부 함수 호출: 컴포넌트 간 통신이 함수 호출/라이브러리 참조로 간단
장점
  • 개발/배포가 단순: 작은 팀, 초기 스타트업에 적합
  • 디버깅/테스트 용이: 모든 로직이 한곳에 있어 파악이 빠름
  • 성능: 모듈 간 통신이 함수 호출로 빠름
  • 관리 도구가 적음: 배포/운영 인프라가 간단
단점
  • 확장성 한계: 서비스가 커질수록 코드/팀/릴리즈 관리가 어려워짐
  • 변경 영향 범위 큼: 일부 기능 변경도 전체 재배포 필요
  • 장애 영향: 한 부분 오류가 전체 서비스 장애로 이어질 수 있음
  • 새로운 기술 도입 난이도: 일부 모듈만 따로 언어나 프레임워크를 바꾸기 힘듦
실제 사례
  • 전통적인 LAMP1 웹서비스, 초기형 스타트업, 예전의 ERP/CRM 시스템
  • Docker의 초기 엔진도 모놀리식 구조(dockerd + 이미지 빌드 + 런 등 모든 기능 결합)

3. Microservice Architecture (마이크로서비스 아키텍처)

정의
  • 애플리케이션을 작고 독립적인 “서비스 단위” 로 분리*
  • 각 서비스는 고유의 책임과 데이터, 실행환경을 가짐
  • 서비스들은 보통 네트워크(API, 메시지 등)로 통신
주요 특징
  • 독립 배포: 각 서비스는 개별적으로 배포/스케일/업데이트 가능
  • 작은 코드베이스: 각 서비스가 작아 관리와 학습이 쉬움
  • 다양한 기술 사용 가능: 서비스별로 다른 언어, 프레임워크, DB 선택 가능
  • 장애 격리: 한 서비스 장애가 전체 시스템에 영향 주지 않음
  • 조직 분리: 기능팀/서비스팀 별도로 운영 가능
장점
  • 확장성: 트래픽 많은 서비스만 선택적 확장 가능
  • 배포 민첩성: 부분적 배포/롤백/업데이트가 쉬움
  • 실험과 변화 용이: 새로운 기술, 언어, DB 적용이 유연
  • 대규모 조직에 적합: 팀 간 독립적 개발/운영
단점
  • 운영 복잡성 증가: 서비스 수가 많아질수록 인프라/네트워크/모니터링 등 관리 부담 증가
  • 통합 테스트 어려움: 서비스 간 통합/시나리오 테스트가 복잡
  • 트랜잭션 관리: 분산 트랜잭션, 데이터 일관성 이슈 발생
  • 서비스 경계 설계의 어려움: 어떻게 분할할지 고민 필요
실제 사례
  • Netflix, 쿠팡, 네이버, 카카오 등 대규모 서비스
  • Kubernetes 기반 클라우드 네이티브 서비스 대부분

4. MSA 운영에 필요한 기술 스택

MSA는 서비스를 나누는 순간 모놀리식에서는 없던 문제들이 생긴다. 이를 해결하기 위해 부수적인 인프라 컴포넌트가 필요하다.

컴포넌트역할대표 도구
API Gateway클라이언트 요청을 적절한 서비스로 라우팅, 인증/인가 처리Kong, AWS API Gateway, Nginx
서비스 디스커버리동적으로 생성/소멸하는 서비스 인스턴스의 위치를 자동 등록·조회Consul, etcd, K8s DNS
서비스 메시서비스 간 통신의 관찰·제어·보안을 인프라 수준에서 처리Istio, Linkerd, Envoy
메시지 브로커서비스 간 비동기 통신, 이벤트 기반 느슨한 결합Kafka, RabbitMQ, NATS
분산 추적여러 서비스를 거치는 요청의 전체 흐름을 추적·시각화Jaeger, Zipkin, OpenTelemetry
중앙 집중 로깅각 서비스의 로그를 한곳에 수집·검색ELK Stack, Loki, Fluentd
컨테이너 오케스트레이션수십~수백 개 서비스의 배포·스케일링·장애 복구 자동화Kubernetes, Docker Swarm

모놀리식에서는 왜 불필요한가

모놀리식에서는 모듈 간 통신이 함수 호출이므로 서비스 디스커버리가 필요 없고, 하나의 프로세스이므로 분산 추적도 불필요하다. 배포 단위가 하나이므로 오케스트레이터 없이도 운영 가능하다. MSA의 운영 복잡성은 이 부수 인프라를 모두 구축·관리해야 하는 데서 온다.


5. MSA와 Kubernetes의 관계

MSA는 아키텍처 패턴이고, Kubernetes는 인프라 도구다. 별개의 개념이지만, 실무에서는 MSA를 운영하면 결국 K8s(또는 유사 오케스트레이터)를 쓰게 된다.

MSA가 요구하는 것K8s가 제공하는 것
서비스별 독립 배포Pod/Deployment 단위 배포
서비스 디스커버리Service, CoreDNS
서비스별 독립 스케일링HPA (Horizontal Pod Autoscaler)
장애 격리·자동 복구Pod 재시작, Liveness/Readiness Probe
로드 밸런싱Service, Ingress
설정 관리ConfigMap, Secret

K8s 위에 올렸다고 MSA가 되는 것은 아니다

모놀리식 앱도 K8s 위에서 잘 돌아간다. MSA의 핵심은 인프라가 아니라 서비스 분리 설계(API 계약, 데이터 소유권, 팀 구조)에 있다. K8s는 MSA 운영을 편하게 해주는 플랫폼이지, MSA 자체는 아니다.


6. Monolithic vs Microservice 비교표

구분모놀리식(Monolithic)마이크로서비스(Microservice)
코드베이스하나여러 개(서비스별)
배포 방식전체 한 번에개별 서비스 단위
장애 영향전체 장애일부 서비스 장애로 국한
확장성전체 스케일업/아웃서비스별 개별 확장
기술 다양성제한됨서비스별 자유
운영 복잡도낮음높음
도입 추천 상황작은 팀/프로젝트, 초기 개발대규모 조직, 빈번한 업데이트/확장

7. 분산 시스템의 고유 문제

MSA는 본질적으로 분산 시스템이다. 모놀리식에서는 존재하지 않았던 문제들이 서비스를 나누는 순간 발생한다.

분산 트랜잭션과 Saga 패턴

모놀리식에서는 하나의 DB 트랜잭션으로 데이터 일관성을 보장할 수 있다. 하지만 MSA에서는 각 서비스가 자체 DB를 소유하므로, 여러 서비스에 걸친 작업을 하나의 트랜잭션으로 묶을 수 없다.

Saga 패턴은 이 문제의 대표적인 해결책이다. 하나의 큰 트랜잭션 대신, 각 서비스의 로컬 트랜잭션을 순차적으로 실행하고, 중간에 실패하면 이전 단계를 보상 트랜잭션(compensating transaction)으로 되돌린다.

주문 생성 → 결제 처리 → 재고 차감 → 배송 요청
                ↑ 실패 시
        주문 취소 ← 결제 환불 ←
  • Choreography 방식: 각 서비스가 이벤트를 발행하고 다른 서비스가 구독하여 반응 (느슨한 결합)
  • Orchestration 방식: 중앙 오케스트레이터가 각 서비스에 순차적으로 명령 (흐름 파악 용이)
Eventual Consistency (최종 일관성)

분산 환경에서는 모든 서비스의 데이터가 항상 일치하는 것(Strong Consistency)을 보장하기 어렵다. 대신 일정 시간이 지나면 결국 모든 서비스의 데이터가 일치하게 된다는 모델을 채택한다.

  • 주문 서비스에서 주문이 생성된 직후, 재고 서비스에는 아직 반영되지 않을 수 있다
  • 하지만 이벤트가 전파되면 결국 재고도 차감된다
  • 이 사이 짧은 불일치 구간이 존재하며, 비즈니스적으로 이를 허용할 수 있는지 판단해야 한다
서비스 디스커버리

MSA에서 서비스 인스턴스는 동적으로 생성·소멸된다. 오토스케일링으로 인스턴스가 늘어나거나, 장애로 교체되면 IP 주소가 바뀐다. 서비스 디스커버리는 이 변화를 자동으로 추적하여, 호출하는 쪽이 항상 유효한 인스턴스를 찾을 수 있게 한다.

  • 클라이언트 사이드 디스커버리: 호출하는 서비스가 레지스트리에서 직접 주소를 조회 (Consul, Eureka)
  • 서버 사이드 디스커버리: 로드 밸런서가 레지스트리를 참조하여 라우팅 (K8s Service, AWS ELB)

8. 모놀리식 → MSA 전환 전략

처음부터 MSA로 시작하기보다, 모놀리식으로 시작한 뒤 필요에 따라 전환하는 것이 일반적이다. 모놀리식의 한계를 직접 겪어야 어떤 서비스를 분리해야 할지 판단할 수 있기 때문이다.

Strangler Fig 패턴

기존 모놀리식을 한 번에 교체하는 것이 아니라, 새 기능부터 독립 서비스로 만들고 기존 기능을 하나씩 이전하는 점진적 전환 방식이다. 교살 무화과(Strangler Fig)가 숙주 나무를 서서히 감싸며 대체하는 것에서 유래했다.

1단계: 모놀리식 앞에 API Gateway 배치
2단계: 새 기능을 별도 서비스로 개발, Gateway가 라우팅
3단계: 기존 기능을 하나씩 서비스로 추출
4단계: 모놀리식에서 해당 기능 제거
→ 반복

전환 시 주의사항

  • DB 분리가 가장 어렵다: 코드를 서비스로 나누는 것보다, 하나의 DB를 서비스별로 분리하는 것이 훨씬 복잡하다. 조인 쿼리 의존성, 데이터 마이그레이션, 일관성 문제가 동시에 발생한다.
  • 팀 구조도 함께 바뀌어야 한다: Conway의 법칙에 따르면, 시스템 구조는 조직 구조를 따른다. 서비스를 나누면서 팀도 서비스 단위로 재편되지 않으면 오히려 커뮤니케이션 비용만 증가한다.

9. 언제 어떤 아키텍처를 선택해야 할까?

  • 모놀리식 추천 상황

    • 작은 팀, MVP/프로토타입 단계
    • 빈번한 구조 변경 없이 빠른 결과물이 필요할 때
    • 복잡한 트래픽/스케일링/기술 혼합 요구가 없는 서비스
  • 마이크로서비스 추천 상황

    • 조직·트래픽 규모가 커지고, 서비스별 독립적 배포/확장이 중요할 때
    • 다양한 언어/기술, 잦은 기능 추가·변경이 필요한 경우
    • 장애 격리, DevOps, CI/CD 등 현대적 개발/운영 프로세스 적용 환경

10. 결론

  • 모놀리식과 마이크로서비스는 “정답과 오답”이 아니라, 상황에 따라 맞는 도구를 고르는 것
  • 모놀리식은 빠른 시작·단순함이 장점, 마이크로서비스는 확장성·유연성이 핵심
  • 처음부터 MSA로 시작하기보다, 모놀리식으로 시작한 뒤 필요에 따라 점진적으로 전환하는 것이 실무적으로 안전하다
  • MSA 도입 시 서비스 분리 설계뿐 아니라, 부수 인프라(Gateway, 메시지 브로커, 분산 추적 등)와 조직 구조까지 함께 고려해야 한다

Footnotes

  1. 가장 널리 사용되던 오픈소스 기반 웹 서버 스택. 리눅스, 아파치, MySQL, PHP.