Skip to content

MycroCosmo/msa-service

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MSA Service Project

이 프로젝트는 마이크로서비스 아키텍처(MSA)를 기반으로 한 e커머스 플랫폼의 백엔드 서비스입니다.
단순히 여러 서비스를 분리하는 데 그치지 않고, 서비스 분리 기준, 통신 방식, 장애 전파, 데이터 정합성에 대한 고민과 학습을 목표로 설계되었습니다.

Spring Boot와 Spring Cloud를 기반으로 각 서비스는 독립적으로 배포 및 확장될 수 있으며,
실제 MSA 환경에서 자주 언급되는 핵심 구성 요소들을 직접 적용하고 검증하는 데 초점을 두었습니다.


프로젝트 목적 및 배경 (Why MSA?)

초기에는 모놀리식 구조가 개발과 배포 측면에서 단순하지만, 서비스 규모가 커질수록 다음과 같은 한계가 발생합니다.

  • 특정 도메인 변경이 전체 애플리케이션 배포로 이어지는 문제
  • 트래픽이 한 기능에 집중될 때 전체 시스템이 영향을 받는 구조
  • 장애 발생 시 영향 범위를 국소화하기 어려움

이 프로젝트는 이러한 모놀리식 구조의 한계를 직접 체감하고,
이를 구조적으로 해결하기 위한 방법으로 MSA를 선택하여 다음 질문에 답하는 것을 목표로 했습니다.

  • 서비스는 어떤 기준으로 분리해야 하는가?
  • 서비스 간 통신 실패는 어떻게 전파되는가?
  • 분산 환경에서 데이터 정합성은 어떻게 다뤄야 하는가?

아키텍처 개요

프로젝트는 다음과 같은 마이크로서비스로 구성되어 있습니다.

  • Gateway Service
    API 게이트웨이 역할을 수행하며, 외부 클라이언트 요청을 적절한 내부 서비스로 라우팅합니다.
    JWT 인증을 중앙에서 처리하여 각 서비스의 보안 로직 중복을 제거했습니다.

  • User Service
    사용자 관리, 인증 및 권한 부여를 담당합니다.
    다른 서비스와 강하게 결합되지 않도록 독립적인 책임을 가집니다.

  • Product Service
    상품 정보 관리 및 조회를 담당합니다.
    주문/결제 도메인과 분리하여 조회 트래픽 증가에도 독립적으로 확장 가능하도록 설계했습니다.

  • Order Service
    주문 생성 및 상태 관리를 담당하며, 비즈니스 트랜잭션의 중심 역할을 합니다.
    Kafka 이벤트 발행의 주체입니다.

  • Payment Service
    결제 처리 및 결제 상태 관리를 담당합니다.
    외부 결제 시스템 연동을 고려하여 장애 격리를 염두에 두고 분리했습니다.


서비스 분리 기준과 설계 원칙

각 서비스는 단순 기능 단위가 아니라
변경 이유가 같은 도메인 단위(Bounded Context) 를 기준으로 분리했습니다.

이를 통해 다음과 같은 점을 학습했습니다.

  • DB 테이블 단위 분리는 MSA가 아님
  • 서비스 간 직접적인 DB 접근은 결합도를 급격히 증가시킴
  • 독립적인 배포와 확장을 위해서는 책임 경계가 명확해야 함

서비스 분리는 기술적 이유가 아닌,
비즈니스 변화에 대응하기 위한 설계 결정임을 이해하게 되었습니다.


기술 스택

  • 프레임워크: Spring Boot 3.5.4
  • 언어: Java 21
  • 빌드 도구: Gradle
  • 서비스 디스커버리: Consul
  • API 게이트웨이: Spring Cloud Gateway
  • 데이터베이스: PostgreSQL
  • 메시징: Apache Kafka
  • 인증: JWT (JSON Web Token)
  • 기타: Lombok, OpenFeign, Spring Data JPA

API Gateway 선택 이유

Spring Cloud Gateway를 사용한 이유는 다음과 같습니다.

  • 각 서비스가 인증/인가 로직을 중복 구현하지 않도록 하기 위함
  • 외부 클라이언트와 내부 서비스 구조를 분리하기 위함
  • 추후 Rate Limiting, 로깅, 공통 필터 확장을 고려

Gateway에서 JWT 검증을 처리함으로써
각 마이크로서비스는 비즈니스 로직에만 집중할 수 있도록 설계했습니다.

이를 통해 보안 로직의 중앙화내부 서비스 단순화의 중요성을 체감했습니다.


서비스 디스커버리 (Consul) 도입 이유

MSA 환경에서는 서비스의 IP와 포트가 고정되지 않기 때문에
정적 설정 기반 통신은 확장성과 안정성에 한계가 있습니다.

Consul을 통해 다음을 경험했습니다.

  • 서비스 인스턴스 증가/감소 시 자동 등록 및 해제
  • Gateway에서 서비스 이름 기반 라우팅
  • 인프라 변경이 애플리케이션 코드에 영향을 주지 않음

이를 통해
서비스 디스커버리는 MSA의 선택이 아니라 전제 조건임을 이해하게 되었습니다.


Kafka를 통한 비동기 이벤트 처리

Order Service와 Payment Service 간 통신에는
동기 REST 호출 대신 Kafka 기반 이벤트 방식을 사용했습니다.

도입 이유는 다음과 같습니다.

  • 주문 생성과 결제 처리를 강하게 결합하지 않기 위함
  • 특정 서비스 장애가 전체 트랜잭션 실패로 이어지지 않도록 하기 위함

이 과정에서 다음을 학습했습니다.

  • 이벤트 기반 구조는 즉시 일관성 대신 결과적 일관성을 요구함
  • 메시지 중복 처리(idempotency)의 중요성
  • 실패 시 재처리 전략(DLQ, retry)의 필요성

이를 통해
MSA는 단순한 분산 구조가 아니라, 실패를 전제로 설계하는 아키텍처라는 점을 체감했습니다.


트랜잭션과 데이터 정합성에 대한 고민

MSA 환경에서는 하나의 글로벌 트랜잭션을 사용하는 것이 어렵기 때문에,
이 프로젝트에서는 다음과 같은 접근을 취했습니다.

  • 서비스 간 DB 트랜잭션을 공유하지 않음
  • 주문 생성 → 이벤트 발행 → 결제 처리 구조
  • 각 서비스는 자신의 데이터에만 책임

이를 통해 다음을 학습했습니다.

  • 2PC 대신 보상 트랜잭션(Saga 패턴)의 필요성
  • 완벽한 일관성보다 명확한 책임 분리가 더 중요함

사전 요구사항

  • Java 21 이상
  • Gradle 7.0 이상
  • PostgreSQL 데이터베이스
  • Consul (서비스 디스커버리용)
  • Apache Kafka (메시징 큐)

설치 및 실행

1. 저장소 클론

git clone <repository-url>
cd msa-service

2. 각 서비스별 빌드

./gradlew build

3. 환경 설정

각 서비스의 application.yml에서 DB 및 Consul 설정을 환경에 맞게 수정합니다.

4. 외부 서비스 실행

  • Consul (port: 8500)
  • PostgreSQL
  • Kafka

5. 서비스 실행

cd gateway-service && ./gradlew bootRun
cd ../user-service && ./gradlew bootRun
cd ../product-service && ./gradlew bootRun
cd ../order-service && ./gradlew bootRun
cd ../payment-service && ./gradlew bootRun

API 엔드포인트

  • Gateway: http://localhost:8080
    • /user/** → User Service
    • /product/** → Product Service
    • /order/** → Order Service
    • /payment/** → Payment Service

프로젝트를 통해 얻은 핵심 인사이트

  • MSA는 기술 문제가 아니라 설계 문제
  • 서비스 분리는 코드가 아닌 변경 이유 기준
  • 장애는 반드시 발생하며, 설계로 흡수해야 함
  • 메시징은 편의가 아니라 결합도를 낮추기 위한 도구
  • 작은 프로젝트일수록 MSA의 비용을 더 명확히 체감할 수 있음

라이선스

이 프로젝트는 MIT 라이선스 하에 배포됩니다.

About

간단한 msa 프로젝트 예제

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages