MSA
하나의 애플리케이션을 여러 개의 독립적인 서비스로 분리하여 개발, 배포, 유지보수를 용이하게 하는 소프트웨어 개발
- 서비스 간의 통신은 주로 HTTP/HTTPS, 메시지 큐를 통해 이루어진다.모놀리틱 아키텍처
- 하나의 큰 코드베이스로 구성된 애플리케이션
- 모든 기능이 하나의 애플리케이션 내에 포함
Spring Cloud
MSA 개발을 위한 도구와 서비스를 제공하는 스프링 프레임워크의 확장
주요 기능
- 서비스 등록 및 디스커버리 : Eureka
- 로드 밸런싱 : Ribbon
- 서킷 브레이커 : Hystrix, Reslilence4j
- API 게이트웨이 : Zuul, Spring Cloud Gateway
- 구성 관리 : Spring Cloud Config
- 분산 추적 : Zipkin
- 메시징 : Spring Cloud Stream
- Eureka*
- 서비스 레지스트리 : 모든 서비스 인스턴스 위치를 저장하는 중앙 저장소
- 헬스 체크 : 서비스 인스턴스 상태를 주기적으로 확인
서버 설정
server:
port: 8761
eureka:
client:
#다른 Eureka 서버에 이 서버를 등록하지 않는다
register-with-eureka: false
#다른 Eureka 서버의 레지스트리를 가져오지 않음
fetch-registry: false
server:
#자기 보호 모드 비활성화
enable-self-preservation: false
클라이언트 설정(각 서비스는 Eureka서버에 자신을 등록해야 한다.)
spring:
application:
name: my-service
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/ #Eureka 서버 URL
register-with-eureka: false # Eureka 서버에 등록
fetch-registry: true # Eureka 서버로부터 레지스트리 정보 가져오기
instance:
hostname: localhost # 클라이언트 호스트 이름
prefer-ip-address: true # IP 주소 사용 선호
lease-renewal-interval-in-seconds: 30 # 리스 갱신 간격
lease-expiration-duration-in-seconds: 90 # 리스 만료 기간
Ribbon
- 서버 리스트 제공자 : Eureka로 부터 인스턴스 리스트 제공받아 로드밸런싱에 사용
- 로드 밸런싱 알고리즘
- Failover : 요청 실패 시 다른 인스턴스로 자동 전환
Resilience4j
- 서킷 브레이커 : 호출 실패 감지
- Fallback : 호출 실패 시 대체 로직 실행
- 타임아웃 설정
- 재시도
Cloud gateway
- 루팅 및 필터링
- 보안
- 효율성
Spring cloud config
- 중앙 집중식 설정 관리
- config서버, config클라이언트(서버에서 설정을 받아 사용)
MSA 프로젝트 생성
멀티 모듈
루트 프로젝트 생성
https://start.spring.io/ 에서 최소한의 의존성만 추가한 뒤 프로젝트 생성
src 제거 : 루트는 하위 모듈과 공통 기능을 담는 디렉토리 역할
setting.gradle
rootProject.name = 'msa-root'
include 'eureka-server'
include 'gateway'
include 'product'
build.gradle
plugins {
id 'java'
id 'io.spring.dependency-management' version '1.1.7' // 의존성 관리용 플러그인 추가
}
group = 'com'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', '2025.0.0') // Spring Cloud BOM 버전 정의
}
subprojects {
group = 'com.sparta.msa_exam'
version = '1.0.0'
apply plugin: 'java'
apply plugin: 'io.spring.dependency-management'
repositories {
mavenCentral()
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21) // or 21 등 원하는 버전
}
}
test {
useJUnitPlatform()
}
}
subprojects 내 booJar
- 각 하위 모듈에서 개별적으로 적용하는 것이 일반적
- 상위 모듈에서는 booJar을 false
- plugins*
- 상위는 java 플러그인 적용하고 하위에서 springframework.boot 적용
- Spring Cloud BOM 설정*
- Spring Cloud 관련 의존성의 버전을 통합 관리할 수 있어 편리
하위 모듈 생성
유레카 서버는 서버로 나머지 서비스들은 클라이언트로 등록
실행은 각 모듈의 메인 클래스를 따로 실행
각 build.gradle(의존성 및 라이브러리)와 application.properties는 다르게 설정한다.
Eureka의 build.gradle
plugins {
id 'org.springframework.boot' version '3.5.4'
id 'io.spring.dependency-management'
id 'java'
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-server'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
test {
useJUnitPlatform()
}
404 오류
API 요청을 보냈으나 응답 없음
원인
application.properties에 logging.level.org.springframework.web=DEBUG 추가
해당 RequestMapping 관련 로그가 보이지 않음
캐시 문제로 생각
해결
Gradle -> Tasks -> build -> Clean
Intellij의 File -> Invalidate and Restart
Task 'prepareKotlinBuildScriptModel' not found in project ':order'.
order 모듈 추가 후 오류 발생
원인
prepareKotlinBuildScriptModel Task는 최상위 프로젝트에서 동작한다
하위 프로젝트(order)가 최상위 프로젝트로 잘못 등록된 것
Gradle 탭의 Tasks Activation으로 확인할 수 있다
'msa-root.order.main' and 'order.main'. Two modules in a project │
│ cannot share the same content root.
하나의 소스 코드 폴더에 두 개의 다른 모듈이 동시에 등록되어 발생
해결
.idea 디렉터리 삭제 (Intellij의 설정 파일)
모든 .imi 파일 삭제(각 모듈의 설정 정보)
Intellij 재시작