여러 프로젝트/패키지/서비스의 코드를 하나의 Git 저장소에 모아 관리하는 방식
정의
- 하나의 애플리케이션(또는 하나의 배포 단위) 안에 기능들이 함께 들어있는 구조.
- 보통 하나의 코드베이스 + 하나의 빌드/배포 산출물(예: 단일 jar/war) + 단일 실행 환경.
특징
-모듈(패키지)로 내부를 나누더라도 배포는 같이 된다.
-서비스 간 호출이 대부분 프로세스 내부 호출(메서드 호출) 이라 단순하고 빠름.
-텍스트초기 개발/운영이 비교적 쉽다.
장점
- 개발/테스트/배포 파이프라인 단순
- 트랜잭션 처리 쉬움(단일 DB, 단일 트랜잭션)
- 로컬 디버깅 쉬움
단점
- 커지면 빌드/배포가 느려지고 변경 영향 범위가 큼
- 부분만 확장(scale)하기 어려움(전체를 같이 늘리는 경우 많음)
- 팀이 커지면 충돌/의존이 커짐
정의
- 기능(도메인)을 여러 독립 서비스로 나누고, 각 서비스가 독립적으로 배포/확장되는 구조.
- 서비스 간 통신은 보통 HTTP/gRPC/메시지 큐 등 “네트워크 호출”이다.
특징
- 서비스별로 DB를 분리하는 경우가 많고(“Database per service” 패턴), 데이터 일관성은 분산 트랜잭션 대신 이벤트/사가(Saga) 등으로 푼다.
- 운영 요소가 늘어난다: 서비스 디스커버리, 관측성(로그/트레이싱), 장애 격리, 배포 자동화 등.
장점
- 서비스 단위로 독립 배포/롤백 가능
- 특정 서비스만 수평 확장 가능
- 팀이 서비스 단위로 오너십을 갖기 쉬움(조직 확장에 유리)
단점
- 분산 시스템 복잡도 상승(네트워크, 장애, 지연, 버전 호환)
- 관측/운영 비용 증가(모니터링, 트레이싱, 배포, 보안)
- 데이터 일관성/트랜잭션이 어려워짐
모놀리식: 기능은 나눠도 배포 단위는 하나
MSA: 기능을 서비스로 나누고 배포 단위도 여러 개
모노레포: 배포 단위가 뭐든 상관없이 코드를 한 레포에 모아 관리
만약 회사에 스토리지/ 메신저/ 명함 서비스가 있다면?
1) 하나의 모놀리식으로 묶는 경우
한 서버(한 앱) 안에 3개 기능이 모듈로 존재
※ 단점:
- 하나의 서비스에 트래픽 폭증 시 전체를 같이 스케일 해야할 수 있음
- 배포 리스크 공유
2) MSA로 서비스를 3개로 분리하는 경우
스토리지 서비스 / 메신저 서비스 / 명함 서비스를 각각 별도 서비스로 둠 (배포 단위 3개)
서비스 간 연결 예시
메신저에서 파일 첨부:
messenger-service가 storage-service에 “파일 업로드용 presigned URL 발급” 요청
업로드 후 messenger-service는 메시지에 fileId만 저장
명함에서 프로필 사진 저장:
card-service가 storage-service를 파일 저장소로 사용
DB는 보통 서비스별로 분리
※단점:
- 운영 난이도 상승(모니터링, 배포, 장애 대응 API 버전관리)
- 서비스 간 호출 실패/지연 고려해야함
모노레포 혹은 멀티레포와의 조합
한 레포에 여러 서비스 코드가 있고, 배포는 서비스별로 따로
레포 구조 예시
company-platform (one repo)
├─ services/
│ ├─ storage-service/
│ ├─ messenger-service/
│ └─ card-service/
├─ packages/
│ └─ common-lib/ (공통 DTO, 유틸, 인증 클라이언트 등)
└─ infra/
└─ k8s/ (배포 매니페스트, 헬름 등)
운영/배포
서버(배포 단위): 3개 (storage / messenger / card)
스케일: 각 서비스만 따로 확장 가능
장애 격리: 메신저 터져도 스토리지/명함이 덜 영향
데이터/통신
DB: 보통 서비스별 분리 (또는 최소한 스키마/계정 분리)
통신: messenger → storage를 HTTP/gRPC로 호출
언제 좋냐?
팀이 커지고, 공통 코드 재사용도 많고, 서비스별 독립 배포가 필요할 때
서비스마다 레포가 따로 있고, 배포도 서비스별로 따로
레포 구조 예시
storage-service-repo
messenger-service-repo
card-service-repo
common-lib-repo (있다면)
운영/배포
서버(배포 단위): 3개
각 팀이 레포/릴리즈를 완전히 독립적으로 가져감
데이터/통신
DB: 서비스별 분리가 자연스러움
통신: 네트워크 호출(HTTP/gRPC), 이벤트(큐) 등
언제 좋냐?
조직이 “서비스별로 완전 독립”이고, 접근 권한/규제가 강하게 나뉠 때
한 레포 + 한 앱(한 배포)
(프론트/백/공통까지 한 레포로 묶는 경우도 흔함)
레포 구조 예시
company-app (one repo)
├─ backend/
│ ├─ storage-module/
│ ├─ messenger-module/
│ └─ card-module/
├─ frontend/
└─ packages/
운영/배포
서버(배포 단위): 1개
배포: 스토리지 기능만 고쳐도 전체를 같이 배포
데이터/통신
DB: 보통 하나(테이블만 도메인별로 나눔)
통신: 내부 메서드 호출 (가장 단순)
언제 좋냐?
초기/작은 팀, 빠른 개발이 중요하고 운영 복잡도를 최소화할 때
핵심
- MSA냐 아니냐는 “배포 단위가 여러 개인가?”
- 모노레포냐 아니냐는 “코드가 한 Git 레포에 모여 있나?”
- 모노레포 + MSA = “코드는 같이, 배포는 따로”
- 멀티레포 + MSA = “코드도 따로, 배포도 따로”
- 모노레포 + 모놀리식 = “코드도 같이, 배포도 같이”