01 MSA
01 MSA
1. MSA
1. MSA(Microservice Architecture)
- 하나의 큰 애플리케이션을 여러 개의 작고 독립적인 서비스로 나누어 개발하고 배포하는 소프트웨어 개발 아키텍처
- 서비스에 필요한 API들을 하나의 프로젝트가 아닌 여러 개의 프로젝트로 나눠서 구현하는 방식
- MSA에서는 독립적으로 분리된 하나의 프로젝트를 서비스(service) <-> 스프링에서 서비스랑 다름.
2. MSA / 모놀리식 구조
- 모놀리식 구조
- 주문, 회원, 결제, 게시판 같은 기능이 전부 하나의 애플리케이션 안에 있음
- 배포도 통째로 한 번에
- 한 부분 터지면 전체 영향 가능
- 코드가 커질수록 복잡도 폭증
- MSA 구조
- 기능 단위로 서비스를 나눔 (예: 주문 서비스, 결제 서비스, 회원 서비스)
- 각각이 독립적인 애플리케이션
- 각각 따로 배포 가능
- 서로는 API(HTTP, gRPC)나 메시지(Kafka 등)로 통신
3. MSA 전환 포인트
- 프로젝트 규모가 크거나 또는 개발자 인원이 너무 많아서 배포 사이클이 느려진 경우
- 모놀리식 아키텍처에서는 도저히 감당할 수 없는 트래픽이 발생하는 경우
- 모놀리식 아키텍처로 인한 장애 전파의 횟수가 잦거나, 한 번의 장애 전파도 서비스에 치명적인 경우
2. MSA의 장점
1. 장애 격리 (Fault Isolation)
- 모놀리식은 한 모듈에서 메모리 누수나 쓰레드 블로킹 터지면 전체 서버가 같이 죽는 경우가 많음.
- MSA는 결제 서비스가 터져도 주문, 상품 조회 같은 다른 서비스는 계속 동작 가능함.
- 대규모 서비스에서 “부분 장애”가 가능해짐
2. 독립 배포 (Independent Deployment)
- 회원 서비스 코드 수정했다고 전체 시스템 빌드·배포할 필요가 없음
- 해당 서비스만 CI/CD로 재배포하면 끝.
- 배포 속도 빨라지고, 변경 리스크가 줄어듬
- 팀별로 배포 스케줄도 분리 가능.
3. 확장성 (Selective Scaling)
- MSA에서는 주문 서비스 인스턴스만 10대로 늘리고, 게시판은 2대 그대로 둘 수 있음.
- 모놀리식이면 전체를 10대로 늘려야 함 → 자원 낭비.
4. 팀 구조와 잘 맞음
- 조직이 커지면 “코드 충돌”이 아니라 “사람 충돌”이 문제
- MSA는 팀이 서비스 단위로 오너십을 가질 수 있음
- 주문팀, 결제팀, 회원팀 식으로 나뉘고 코드 영역이 겹치지 않음.
5. 기술 스택 유연성
- 특정 언어/프레임워크에 묶이지 않음
- 결제는 Java
- 추천은 Python
- 실시간 채팅은 Node
6. 배포 안정성 향상
- 하나의 거대한 배포보다, 작은 단위의 잦은 배포가 더 안전해짐
- 문제 생기면 해당 서비스만 롤백.
3. MSA의 주의점
1. 구조 복잡도 폭증
- 코드가 아니라 “시스템”이 어려워짐
- 개발자가 신경 써야 할 레이어가 갑자기 늘어남
- 모놀리식: 메소드 호출 → 끝
- MSA: 네트워크 호출 → 타임아웃 → 재시도 → 서킷 브레이커 → 장애 전파 → 모니터링 필요
2. 네트워크 실패 가능성
- 같은 JVM 안의 메소드 호출은 거의 실패 안함.
- 서비스 간 HTTP 호출은 Retry, Timeout, Circuit Breaker, Bulkhead 같은 패턴이 필요
- 타임아웃
- 부분 응답
- 네트워크 단절
- 중복 요청
3. 트랜잭션이 어려움
- 모놀리식은 DB 하나에서 트랜잭션 걸면 끝.
- MSA에서는
- 주문 DB + 결제 DB + 재고 DB 이걸 한 번에 롤백할 수 없음
- SAGA 패턴 같은 복잡한 설계를 해야 하고,
- 데이터 일관성을 “포기하고 결국 맞추는 방식(Eventual Consistency)”으로 자주감
- 운영 난이도 급상승
- MSA는 “운영 아키텍처”
- 서비스 디스커버리
- API Gateway
- 중앙 로그 시스템 (ELK 등)
- 분산 추적 (Zipkin, Jaeger)
- 모니터링 (Prometheus, Grafana)
- 컨테이너 오케스트레이션 (Kubernetes)
4. 디버깅이 어려움
- 요청 하나가 Gateway → 주문 → 결제 → 재고 → 알림 이렇게 5개 서비스를 거칠 수 있음
- 문제 생기면 로그를 5군데서 추적해야 함.
5. 테스트가 어려움
- 단위 테스트는 쉬워도, 서비스 간 통합 테스트는 복잡함
- 로컬에서 전체 시스템 띄워야 하고, 메시지 브로커, DB 여러 개 필요.
6. 초기 비용이 높음
- 작은 서비스에 MSA 쓰면 비즈니스 문제보다 인프라 문제를 더 많이 다루게 됨
- 실제 기능 개발 속도는 오히려 느려짐
4. Memo
1. 스프링기준 대략적인 케이스
| 구분 | 통신 방식 | 사용 기술 | 동작 흐름 | 이런 상황에 사용 | 특징 요약 |
|---|---|---|---|---|---|
| 1 | 동기 HTTP 통신 | RestTemplate, WebClient, OpenFeign | A 서비스 → HTTP 요청 → B 서비스 → 응답 반환 | 즉시 결과가 필요한 기능 (결제 승인, 재고 확인, 로그인 인증 등) | 호출한 쪽이 기다림. 구조 단순하지만 장애 전파 쉬움 |
| 2 | 비동기 이벤트 통신 | Spring for Apache Kafka, Spring AMQP(RabbitMQ) | A 서비스 → 이벤트 발행 → 브로커(Kafka) 저장 → B/C 서비스가 각자 소비 | 알림 발송, 로그 처리, 통계 집계, 주문 후 후속 작업 등 | 느슨한 결합. 응답 안 기다림. MSA에 가장 어울림 |
| 3 | API Gateway 경유 | Spring Cloud Gateway | 클라이언트 → Gateway → 내부 서비스로 라우팅 | 외부 사용자가 여러 서비스를 호출할 때 | 인증, 로깅, 공통 처리 담당. 서비스 간 통신용이 아니라 “입구” 역할 |
| 4 | 서비스 디스커버리 기반 호출 | Eureka + OpenFeign/WebClient | A 서비스 → 서비스 이름으로 호출 → 디스커버리가 실제 주소 연결 | 컨테이너 환경에서 IP가 계속 바뀌는 경우 | 서비스 위치를 코드에 안 박아도 됨 |
| 5 | gRPC (고성능 내부 통신) | grpc-spring-boot-starter 등 | A 서비스 → gRPC 호출 → B 서비스 | 내부 서비스 간 고성능, 저지연 통신 필요 시 | HTTP보다 빠름. 대신 구현 난이도 조금 있음 |
2. MVC + MailService + SMSService
- 흐름
- 사용자가 회원가입 요청
- MVC 컨트롤러 → 회원 서비스 로직 수행
- 회원 저장 완료
- 알림 서비스
- 메일 서비스 API 호출
- 문자 서비스 API 호출
- MVC가 “오케스트레이터(조정자)” 역할
- 하지만, MVC가 죽거나 문제가 생기면 service들이 죽을 우려가있음.
- MSA와 모놀리식의 중간점 같은느낌
3. 중간 라우터
- MVC
- Notification Router 서비스
- 메일 서비스
- 문자 서비스
- 문제는
- 불필요한 중간 계층 증가
- Router가 장애나면 알림 기능 전체 죽음
- 결국 Router가 또 하나의 거대한 서비스가 됨 (새로운 모놀리식 위험)
This post is licensed under CC BY 4.0 by the author.