Spring 개발일지

[개인 프로젝트] Spring Boot MSA 프로젝트 구조 설계 및 기능 구현

김둘리 2026. 4. 11. 10:00

이번 개인 프로젝트는 Spring Boot와 IntelliJ를 사용해서 MSA(Microservices Architecture) 구조로 간단한 커머스 시스템을 만들어보는 것이 목표였다.

일주일이라는 짧은 기간 안에 1차적으로 기능 구현을 완료하고, 이후 Eureka, Gateway, Feign Client를 붙이는 것을 목표로 잡았다.

 

기술 스택

  • Java 17
  • Spring Boot 3.5.13
  • Spring Cloud 2024.0.0
  • Spring Data JPA
  • PostgreSQL
  • Gradle 멀티 모듈
  • Lombok

 

프로젝트 구조

Gradle 멀티 모듈 방식으로 4개의 서비스를 하나의 루트 프로젝트 안에서 관리했다.

msa-project/
├── build.gradle          ← 공통 설정
├── settings.gradle       ← 모듈 등록
├── user-service/         ← 회원 서비스 (8081)
├── product-service/      ← 상품 서비스 (8082)
├── order-service/        ← 주문 서비스 (8083)
└── notification-service/ ← 알림 서비스 (8084)

루트 build.gradle 에서 공통 의존성을 관리하고, 각 서비스별로 필요한 의존성만 따로 추가하는 방식으로 구성했다. 이렇게 하면 나중에 Eureka Server나 Gateway 같이 JPA가 필요 없는 서비스를 추가할 때 불필요한 의존성이 딸려오지 않는다.

 

도메인 설계

사용자 계층

  • Consumer (소비자)
  • Seller (판매자)

서비스별 기능

User Service

  • 회원가입
  • 로그인

Product Service

  • 상품 생성
  • 상품 단건 조회
  • 상품 목록 조회 (페이징, 이름 검색)
  • 재고 증가 / 감소

Order Service

  • 주문 생성
  • 주문 상세 조회
  • 주문 목록 조회 (유저별 / 전체)
  • 주문 취소

 

-> 알림 서비스도 있는데 일단 모든 기능 구현 후 후순위로 미뤄둠!! (구현 예정)


패키지 구조

각 서비스는 아래 패키지 구조를 따랐다.

com.example.{service}/
├── domain/       ← 엔티티, Enum
├── dto/          ← Request, Response, Command
├── repository/   ← JPA Repository
├── application/  ← 비즈니스 로직 (Service)
└── presentation/ ← 컨트롤러

Command 패턴을 사용해서 Controller에서 받은 Request를 Command로 변환한 뒤 Service에 전달하는 방식으로 구현했다. 이렇게 하면 Service가 외부 요청 형식에 의존하지 않아서 나중에 수정이 용이하다.

 

DB 전략

MSA에서는 원칙적으로 서비스별로 DB를 분리해야 한다. 하지만 1차 목표가 빠른 기능 구현이었기 때문에 일단 하나의 PostgreSQL DB(msa_project) 안에서 테이블만 분리하는 방식으로 진행했다.

JPA의 ddl-auto: update 설정 덕분에 서비스 실행 시 테이블이 자동으로 생성된다.

 

주요 설계 포인트

1. common 모듈을 만들지 않았다

이전 프로젝트에서는 공통 예외 처리, 공통 응답 형식 등을 common 모듈로 관리했는데, 이번 프로젝트에서는 일단 만들지 않았다. 

-> 튜터님과 상담 후 common 모듈이 필요하다면 추가 예정

2. UUID 기반 ID 전략

UUID를 PK로 사용했다. 나중에 서비스 간 ID 충돌 없이 독립적으로 확장하기 위한 선택이다.

3. 재고 차감 로직을 2차 목표로 미뤘다

주문 생성 시 product-service에 재고 차감 요청을 해야 하지만, 현재는 Feign Client가 없기 때문에 일단 주문 생성만 처리하고 재고 차감은 Feign Client 도입 시 연동할 예정이다.

 

다음 단계

  • 2차 목표: Eureka Server + Spring Cloud Gateway 구성, Feign Client를 통한 서비스 간 통신 및 재고 차감 연동
  • 3차 목표: Kafka를 활용한 비동기 메시징, Redis 캐싱, Prometheus + Grafana 모니터링

 

처음으로 멀티 모듈 MSA 구조를 혼자 직접 설계하고 구현해봤다. 모놀리스 구조에서는 당연하게 쓰던 공통 코드들을 서비스마다 따로 작성하는 것이 처음엔 중복처럼 느껴졌지만, 그게 오히려 각 서비스가 독립적으로 배포되고 변경될 수 있는 기반이 된다는 걸 이해하게 됐다.

2차 목표인 Eureka + Gateway + Feign Client 구성도 빠르게 진행해볼 예정이다.