이 글은 모놀리식 형태인 저의 사이드 프로젝트(E-Commerce)를 MSA 형태로 도메인별 배포단위를 분리 한다고 가정하고 생기는 트랜젹선 처리 문제들을 고민해보고 해결방안을 생각해 보는 과정을 정리한 글입니다,.
1. 모놀리식 & 마이크로서비스(MSA)

<출처 - rancher>
1-1. 모놀리식 아키텍처
모놀리식 아키텍처는 보통 단일 코드 기반의 애플리케이션을 말합니다. 다른 말로는 하나의 애플리케이션이 모든 기능을 포함하고 있는 구조라고도 할 수 있습니다. 또한, 단일한 배포 단위로 관리되는 특징이 있습니다.
📌 모놀리식 아키텍처의 장점
1. 개발 및 배포가 간단하다
모든 기능이 하나의 애플리케이션으로 통합되어 있기 때문에 단일 코드베이스에서 개발하고 배포할 수 있습니다.
별도의 서비스 간 통신을 고려할 필요가 없으며, 모든 기능을 한 번에 업데이트할 수 있어 배포 과정이 단순합니다.
2. 성능이 뛰어나다
모놀리식 아키텍처에서는 서비스 간 네트워크 호출이 필요 없고, 메모리 내에서 빠르게 함수 호출이 이루어집니다.
마이크로서비스 아키텍처에서는 서비스 간 REST API 또는 메시지 큐를 이용한 통신이 필요하지만, 모놀리식에서는 이런 오버헤드가 없기 때문에 성능이 더 좋을 수 있습니다.
3. 개발 환경이 단순하다
개발자가 여러 개의 마이크로서비스를 신경 쓸 필요 없이, 하나의 프로젝트에서 모든 기능을 개발할 수 있습니다.
이는 특히 소규모 팀에서 개발할 때 유리합니다.
4. 테스트가 용이하다
모놀리식 애플리케이션은 단일 프로세스에서 실행되기 때문에 통합 테스트가 비교적 쉽습니다.
마이크로서비스 아키텍처에서는 여러 개의 독립적인 서비스가 서로 협력해야 하므로, 테스트 환경을 구축하는 것이 더 어렵고 복잡할 수 있습니다.
📌 모놀리식 아키텍처의 단점
1. 코드베이스가 커지면서 유지보수가 어려워진다
처음에는 하나의 프로젝트로 시작하기 때문에 개발이 편리하지만, 시간이 지날수록 코드베이스가 커지면서 코드가 복잡해지고 관리가 어려워질 수 있습니다. 특히, 여러 개의 기능이 한 곳에서 관리되면 하나의 변경 사항이 예상치 못한 다른 부분에 영향을 줄 가능성이 커집니다.
2. 빌드 및 배포 시간이 증가한다
애플리케이션이 커질수록 코드 변경 후 컴파일, 테스트, 배포하는 과정이 점점 더 느려집니다.
마이크로서비스는 개별적으로 배포할 수 있지만, 모놀리식에서는 작은 변경이라도 전체 애플리케이션을 다시 빌드하고 배포해야 합니다.
3. 확장(Scale-out)이 어렵다
모놀리식 애플리케이션은 수평 확장(Scale-out, 여러 서버에서 병렬 처리)이 어렵습니다.
마이크로서비스는 특정 기능만 분리하여 독립적으로 확장할 수 있지만, 모놀리식은 전체 시스템을 함께 확장해야 하기 때문에 비용이 증가할 수 있습니다.
4. 기술 스택 변경이 어렵다
모놀리식에서는 하나의 기술 스택(Java, Spring Boot, MySQL 등)을 선택하면, 이를 전체 시스템에서 사용해야 합니다.
반면 마이크로서비스는 각 서비스별로 적절한 기술을 선택할 수 있기 때문에 더 유연한 개발이 가능합니다.
1-2. 마이크로서비스 아키텍처(MSA)
마이크로서비스 아키텍처(MSA)는 애플리케이션을 여러 개의 독립적인 서비스(모듈)로 구성하는 방식을 말합니다!
각 서비스는 독립적으로 개발, 배포 , 확장이 가능하며 보통 REST API, 메시지 큐(Kafka) 등을 통해 서로 통신합니다.
또한, 각 서비스는 독립적인 데이터베이스를 가질 수도 있고 공통 데이터베이스를 사용할 수 있습니다.
📌 마이크로서비스 아키텍처의 장점
1. 독립적인 개발 및 배포 가능
- 서비스마다 별도의 개발팀이 독립적으로 개발할 수 있습니다.
- 특정 서비스만 변경하고 배포할 수 있어 전체 시스템을 다시 빌드할 필요가 없습니다.
- 예를 들어, 주문(Order) 서비스만 수정하면, 다른 서비스에는 영향을 주지 않고 배포할 수 있습니다.
2. 확장성이 뛰어납니다.
- 특정 서비스에만 트래픽이 집중되더라도 해당 서비스만 확장하면 됩니다.
- 예를 들어, "결제 서비스"에 부하가 몰리면 결제 서비스만 추가 서버를 늘려 확장할 수 있습니다.
- 클라우드 환경(AWS, GCP, Azure)과 잘 맞으며, 탄력적인 확장이 가능합니다.
3. 다양한 기술 스택을 사용할 수 있습니다.
- 각 서비스별로 자유롭게 프로그래밍 언어, 데이터베이스, 프레임워크를 선택할 수 있습니다.
4. 장애 격리 및 안정성 증가
- 특정 서비스에 장애가 발생해도 다른 서비스는 정상적으로 동작할 수 있습니다.
- 예를 들어, "알림(Notification) 서비스"가 다운되어도 "주문(Order) 서비스"는 정상적으로 동작할 수 있습니다.
5. 빠른 개발 속도 & CI/CD 적용 용이
- 서비스별로 독립적인 배포가 가능하기 때문에 CI/CD 를 효율적으로 적용할 수 있습니다.
- 새로운 기능을 빠르게 개발하고, 배포 속도를 높일 수 있습니다.
📌 마이크로서비스 아키텍처의 단점
1. 서비스 간 복잡한 통신
- 각 서비스가 분리되어 있기 때문에 서비스 간 통신이 필요합니다.
- REST API, gRPC, 메시지 큐(RabbitMQ, Kafka) 등을 사용해야 하고, 이를 관리하는 추가적인 인프라 비용이 발생할 수 있습니다.
2. 데이터 일관성 유지가 어렵습니다.
- 각 서비스가 자신만의 데이터베이스를 가질 경우, 데이터 일관성을 유지하기 어려울 수 있습니다.
- 예를 들어, 주문(Order) 서비스에서 상품(Product) 재고를 차감해야 하는데, 동기화가 제대로 되지 않으면 데이터 충돌이 발생할 수 있습니다.
- SAGA 패턴 등의 기법을 활용해야 합니다.
3. 초기 설계 및 구축이 복잡함
- MSA를 도입하려면 서비스 간 통신, 장애 복구 전략, 로깅, 모니터링 등의 인프라를 미리 설계해야 합니다.
- 또한, 각 서비스의 배포 및 운영을 관리하는 DevOps 역량이 필요합니다.
4. 운영 및 배포 자동화 필요
- 서비스가 많아지면 각 서비스의 배포 및 운영을 자동화해야 합니다.
- 이를 위해 Docker, Kubernetes(K8s), CI/CD(Jenkins, GitHub Actions) 같은 DevOps 도구가 필수적입니다.
1-3 . 모놀리식에서 마이크로서비스로 전환해야 할 때
처음에는 모놀리식으로 시작했지만, 애플리케이션이 성장하면서 마이크로서비스로 전환을 고민하는 상황들을 정리 해봤습니다.
- 개발 속도가 점점 느려지고 있다
- 배포 시간이 너무 길어지고 있다
- 서비스의 일부만 확장하고 싶은데, 전체를 확장해야 하는 경우가 많다
- 팀이 커지면서 서로 다른 기능을 독립적으로 개발하고 싶다
2. MSA에서 트랜잭션 처리 한계와 해결방안
모놀리식 아키텍처에서 하나의 데이터베이스 안에서 트랜잭션을 처리하는 것은 비교적 간단하지만 서비스가 커지면서 각 도메인별로 배포 단위를 분리(MSA)하면, 기존처럼 단일 트랜잭션을 유지하는데 어려움이 생깁니다.
이 목차에서는 MSA 환경에서 트랜잭션 처리의 한계를 살펴보고, 해결방안을 생각해보고 정리하겠습니다!
2-1. 트랜잭션 처리의 한계
✅ 분산 트랜잭션의 어려움
- 기존의 단일 DB에서는 @Transactional을 통해 원자성(Atomicity)을 보장할 수 있었지만,
MSA에서는 하나의 비즈니스 로직이 여러 서비스와 데이터베이스를 거치므로 트랜잭션을 보장하기 어려울 수 있습니다.
✅ 네트워크 장애로 인한 데이터 불일치
- 서비스 간 통신은 네트워크를 거치므로 장애가 발생할 가능성이 있습니다.
- 예를 들어, 주문이 성공했지만 포인트 차감 API 요청이 실패하면 데이터가 꼬이는 문제가 발생
✅ 롤백 처리가 어려울 수 있습니다.
- 모놀리식에서는 rollback()으로 한 번에 되돌릴 수 있었지만,
- MSA에서는 이미 처리된 요청을 원상 복구하는 로직을 별도로 구현해야 할 수 있습니다.
2-2. 해결방안
✅ SAGA 패턴을 활용한 보상 트랜잭션
SAGA 패턴은 하나의 트랜잭션을 여러 개의 작은 트랜잭션으로 나누어 처리하는 방식입니다.
각 서비스가 독립적으로 트랜잭션을 수행하고, 실패 시 보상(Compensation) 로직을 실행하여 데이터를 정합성 있게 유지할 수 있습니다.
- 오케스트레이션(Orchestration) 방식
- 중앙의 SAGA Coordinator(중앙 관리자느낌) 가 트랜잭션을 관리
- 실패 시 자동으로 보상(Compensation) 로직 실행
- 예: 주문 생성 → 포인트 차감 → 결제 완료 (어느 단계에서든 실패하면 롤백)
- 체인(Choreography) 방식
- 서비스들이 이벤트 기반으로 각자 트랜잭션을 실행하며 다음 단계로 진행
- 중앙 컨트롤러 없이 각 서비스가 이벤트를 구독해서 처리
- 예: 주문 서비스 → 포인트 차감 이벤트 발행 → 포인트 서비스에서 이벤트 수신 후 처리
✅ 최종 일관성 보장
모놀리식에서는 DB 트랜잭션으로 즉각적인 일관성을 유지했지만, MSA에서는 서비스 간 데이터 동기화가 늦어질 수 있습니다.
이를 해결하기 위해 Kafka, RabbitMQ 같은 메시지 큐를 사용하여 이벤트 기반 비동기 처리를 수행할 수 있습니다.
✅ TCC 패턴 적용
TCC 패턴은 트랜잭션을 Try(예약) → Confirm(확정) → Cancel(취소) 의 3단계로 나누어 관리하는 방식입니다.
예를 들어, 주문과 포인트 차감을 처리할 때 먼저 Try 단계에서 포인트를 예약하고, 결제 성공 시 Confirm, 실패 시 Cancel을 호출하여 원자성을 보장할 수 있습니다.