1. 문제 상황
기존의 모놀로틱 아키텍처에서는 모든 기능이 하나의 코드베이스에서 동작하여 서비스 간 결합도가 높고, 확장성과 유지보수성이 제한되는 문제가 발생했다. 이를 해결하기 위해 도메인 주도 설계(DDD, Domain-Driven Design) 원칙을 적용하여 MSA(Microservices Architecture)로 전환하는 방안을 고려했다.
하지만, 무조건적으로 서비스를 잘게 분리하면 오히려 결합도가 높아지고 성능 저하 및 복잡성이 증가할 가능성이 있어 서비스 간 결합도를 고려하여 적절한 기준을 설정하여 분리하는 것이 중요했다.
2. MSA 분리 기준
(1) DDD 원칙에 기반한 서비스 분리
MSA를 설계할 때 가장 중요한 것은 도메인의 경계를 명확하게 나누는 것이다. 이를 위해 DDD의 Bounded Context(경계 컨텍스트) 개념을 적용하여 각 서비스가 독립적인 도메인 로직을 가지도록 구성했다. 그러나, 서비스 간의 트랜잭션 처리, 데이터 일관성 유지, 성능 고려, 네트워크 요청 수 증가 고려 등의 이유로 너무 세분화된 서비스는 묶어서 운영하는 전략을 사용하기로 했다.
3. 실제 프로젝트의 서비스 분리
아래와 같이 비즈니스 도메인과 트래픽 특성을 고려하여 MSA를 구성했다.
(1) user-chat 서비스
- 분리 이유: 우리 프로젝트에서는 채팅이 상품 주문 완료 후에만 가능하므로, 주문과 채팅 중 트래픽이 몰릴 경우 주문이 우선순위를 가져야 한다.
- 서비스 결합도 고려: 채팅은 주문과 완전히 독립적이지 않으므로 완전히 분리하지 않고 같은 서비스에서 운영
- 설계 방향:
- 주문 관련 로직을 우선 실행하고, 채팅 요청은 비동기 메시징 시스템(Kafka, RabbitMQ 등)을 활용하여 처리
- 채팅 서버는 주문 서버와 분리된 워커(worker) 또는 비동기 큐 방식으로 운영
(2) game-product-review-order 서비스
- 분리 이유:
- 게임 → 상품 → 주문 → 리뷰로 이어지는 선형적인 관계를 가지는 도메인
- 상품과 주문은 락(Lock) 관리가 필요하여 강한 결합도를 가짐
- 리뷰는 주문이 있어야만 생성 가능하므로 해당 도메인에 포함
- 설계 방향:
- 상품과 주문은 트랜잭션을 유지해야 하므로 하나의 서비스에서 운영
- 리뷰는 트랜잭션 요구사항이 적지만, 주문과 긴밀하게 연결되므로 같은 서비스에서 관리
- 데이터 정합성을 위해 이벤트 소싱(Event Sourcing) 또는 CQRS 적용 검토
(3) security 서비스
- 분리 이유:
- 보안 관련 기능(인증, 권한 관리 등)은 다른 도메인과 직접적인 연관이 없음
- 서비스 전체의 보안 레이어로 동작해야 함
- 설계 방향:
- JWT, OAuth2, SSO 등을 활용하여 인증 기능 구현
- API Gateway에서 인증 및 권한 관리 수행
- 인증/인가 로직이 필요한 서비스에서 security 서비스와 통신하도록 구성
(4) payment-bill 서비스
- 분리 이유:
- 결제 서비스는 트래픽이 급격히 증가할 가능성이 높음
- 결제 데이터는 강한 일관성이 필요하며, 스케일링을 고려해야 함
- 설계 방향:
- 결제 시스템은 **독립적인 데이터베이스(RDS)**를 사용하여 확장성 확보
- 트랜잭션 안전성을 유지하기 위해 읽기/쓰기 분리(Read Replica 적용)
- 트래픽 증가 시 Auto Scaling을 적용하여 결제 처리량 조절
- 외부 결제 시스템(PG사)과의 통합을 고려하여 API 라우팅 최적화
(5) community-comment 서비스
- 분리 이유:
- 트래픽이 가장 많이 몰리는 서비스이므로, 독립적으로 확장 가능해야 함
- 커뮤니티와 댓글은 관계가 있지만, 높은 트래픽을 처리하기 위해 분리가 필요
- 설계 방향:
- 데이터베이스 RDS를 읽기/쓰기 분리하여 트래픽 부하 감소
- 캐싱(Redis, ElasticSearch 등) 도입하여 성능 최적화
- Kafka와 같은 메시지 큐를 활용하여 비동기 처리 도입
- API Gateway에서 Rate Limiting 적용하여 DDoS 공격 방어
4. 결론
(1) 적용한 MSA 분리 원칙
- DDD 원칙에 따라 도메인을 명확하게 구분하여 서비스 분리
- 트랜잭션 및 강한 결합이 필요한 서비스는 묶어서 운영하여 데이터 정합성을 유지
- 트래픽 분산이 중요한 서비스는 별도로 분리하여 확장성 확보
- 읽기/쓰기 부하를 분산하기 위해 RDS의 Read Replica 및 Auto Scaling 활용
(2) 예상되는 효과
1. 확장성 향상 → 서비스별로 독립적인 스케일링이 가능하여 성능 최적화
2. 배포 유연성 증가 → 특정 서비스만 개별 배포 가능하여 배포 속도 증가
3. 트래픽 처리 최적화 → 결제, 커뮤니티 등 고트래픽 서비스의 성능 향상
4. 데이터 정합성 유지 → 강한 결합이 필요한 도메인은 묶어서 관리하여 안정성 유지
(3) 향후 개선 방향
- 서비스 간 통신에서 성능 최적화를 위해 gRPC 적용 검토
- 데이터 정합성을 높이기 위해 이벤트 소싱(Event Sourcing) 및 CQRS 적용 검토
- 모니터링 강화를 위해 Prometheus, ELK Stack을 활용한 실시간 로깅 및 트래픽 분석 도입
이번 MSA 분리는 현재 프로젝트의 구조와 트래픽 특성을 고려하여 최적의 아키텍처를 설계하는 데 집중하였다. 향후 운영 과정에서 지속적으로 성능 및 확장성을 고려하여 개선해 나갈 계획이다.
'트러블슈팅&기술선택' 카테고리의 다른 글
Elasticsearch 인덱스 확장 (0) | 2025.03.23 |
---|---|
Elasticsearch의 형태소 분석 (0) | 2025.03.22 |
Elasticsearch에서 왜 review를 logstash로 저장했고 가능했는가? (0) | 2025.03.21 |
Elasticsearch와 트랜잭션 락 문제 해결 (0) | 2025.03.21 |
Elasticsearch의 보안 의사결정 (0) | 2025.03.20 |