SPRING

[Spring] MSA(MicroService Architecture) 구현

sagecode 2025. 4. 9. 16:07

왜 마이크로서비스를 구현하게 되었는가?

기존에는 하나의 Spring Boot 프로젝트 안에 결제, 주문, 인증.인가 등의 기능을 모두 넣는 방식으로 개발을 해왔지만, 실제 서비스에서는 각 도메인을 독립적으로 분리해서 관리하는 방식이 더 일반적이다.

 

왜 단일 프로젝트가 아닌 마이크로서비스로 구성했는가?

단일 모놀리식(Monolithic) 아키텍처는 개발 초기에는 구조가 간단하고 빠르게 구축할 수 있다는 장점이 있다. 하지만 기능이 많아질수록 다음과 같은 문제들이 생긴다:

  • 코드베이스가 커져 유지보수가 어려움
  • 빌드/배포 시 전체 시스템이 영향을 받음
  • 도메인마다 다른 팀이 협업하기 힘듦
  • 특정 기능 하나가 문제가 생기면 전체 서비스에 영향을 줄 수 있음

반면 마이크로서비스 아키텍처는 각 기능(예: 결제, 주문, 인증.인가 등)을 독립적인 서비스로 분리하고, 각각 다른 서버(포트)에서 동작시킨다. 이를 통해 확장성, 독립적인 배포, 도메인 단위의 분리 개발이 가능해진다.

 

출처 : https://freeend.tistory.com/115

멀티모듈 기반 마이크로서비스 프로젝트 설정


인증/인가, 주문, 결제 모듈을 따로 분리하는 예시프로젝트를 만들어보자

auth-service, order-service, payment-service, 그리고 공통 모듈인 common-lib를 각각 분리된 모듈로 구성했다.

microservices-template/
├── build.gradle
├── settings.gradle
├── common-lib/
│   └── build.gradle
├── auth-service/
│   └── build.gradle
├── order-service/
│   └── build.gradle
├── payment-service/
│   └── build.gradle

전체 프로젝트(root 프로젝트)내에 build.gradle과 settings.grade을 두고

공통 모듈인 common-lib와 3개의 개별 모듈 auth-service, order-service, payment-service를 만들었다.

 

이 때, 처음에는 개별 모듈과 공통 모듈 각각에도 settings.gradle을 만들었었다. 그런데 계속

Build file '/Users/sanghwapark/Desktop/microservices-template/auth-service/build.gradle' line: 27

A problem occurred evaluating root project 'auth-service'.
> Project with path ':common-lib' could not be found in root project 'auth-service'.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

이런 오류가 발생하였다. 그 이유를 계속 찾다보니, auth-service가 루트 프로젝트처럼 인식되고, common-lib를 찾지 못하는 상태였다.

 

settings.grade의 역할

1. 루트 프로젝트 이름 정의

rootProject.name = 'microservices-template'

프로젝트의 이름을 정해주는 역할을 한다.

 

2. 하위 모듈(Subprojects) 등록

include 'common-lib'
include 'auth-service'
include 'order-service'
include 'payment-service'

 

Gradle에게 이 프로젝트는 여러 개의 하위 모듈로 구성되어 있다라고 알려주는 역할을 한다. 이걸 등록해야 implementation project(':common-lib') 같은 의존성 연결이 동작한다.

공통 모듈 common-lib/build.gradle

plugins {
    id 'java'
}

group = 'com.example'
version = '1.0.0'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

 

common-lib은 Spring Boot가 필요하지 않기 때문에 spring-boot 플러그인을 포함하지 않아도 된다.

 

개별 모듈(인증/인가) auth-service/build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.1'
    id 'io.spring.dependency-management' version '1.1.4'
}

group = 'com.example'
version = '1.0.0'

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation project(':common-lib') # 공통 모듈 의존성 주입
    
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

test {
    useJUnitPlatform()
}

"implementation project(':common-lib')" 을 통해 공통 모듈에 있는 기능들을 사용 가능하다. 다른 서비스(order-service, payment-service)도 이와 동일한 설정 구조를 따른다.

auth-service/application.yml

server:
  port: 8083

각 서비스는 server.port만 다르게 설정하여 실행된다. (order-service는 8081, payment-service는 8082)