MSA (Micro Service Architecture)
common-module 공통적으로 코드
gateway(입구/출구) + 인증처리
*-service 는 개별 DB를 가지게 된다.
auth-service 인증처리(JWT 만든다.)
유저 정보 가지고 있는다.
store-service 가게 정보 / 메뉴 정보
order-service 주문 정보
1. 컨테이너 프로젝트
common, gateway, 각 서비스를 담는 용도의 껍데기 프로젝트.
핵심: src 폴더를 제거한다.



build.gradle
plugins {
id 'java'
// 하위 모듈에서 사용할 플러그인들의 버전을 여기서 중앙 제어합니다.
// apply false는 루트 프로젝트 자체에는 이 기능을 적용하지 않겠다는 뜻입니다.
id 'org.springframework.boot' version '4.0.5' apply false
id 'io.spring.dependency-management' version '1.1.7' apply false
}
// 모든 하위 모듈에 공통으로 적용되는 설정
subprojects {
// 1. 플러그인 먼저 적용, 모든 모듈에서 공통으로 사용하는 의존성 (Lombok 등)
apply plugin: 'java'
apply plugin: 'java-library'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
group = 'com.green.eats'
version = '0.0.1'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-webmvc'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-starter-actuator-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
ext {
set('springCloudVersion', "2025.1.1")
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
}
tasks.named('jar') { enabled = false }
container - .gitignore
## 모든 모듈에 있는 application.yaml파일은 git관리에서 제외한다.
**/src/main/resources/application.yaml
모든 모듈 공통
*.yaml 파일의 인코딩 모두 UTF-8로 변경
.gitattributes, .gitignore 파일은 삭제
common 모듈



common - build.gradle
// Parent의 subprojects에서 이미 플러그인을 apply 했으므로
// 자식에서는 plugins 블록을 비우거나 생략해도 됩니다.
dependencies {
compileOnly 'io.jsonwebtoken:jjwt-api:0.13.0'
compileOnly 'io.jsonwebtoken:jjwt-impl:0.13.0'
compileOnly 'io.jsonwebtoken:jjwt-jackson:0.13.0'
compileOnly 'org.springframework.boot:spring-boot-starter-security'
compileOnly 'org.springframework.boot:spring-boot-starter-data-jpa'
}
// 라이브러리이므로 실행 파일(jar) 생성 방식을 변경
bootJar { enabled = false } // 실행 가능한 jar를 만들지 않음 (메인 메소드가 없으므로)
jar { enabled = true } // 다른 모듈에서 부품으로 쓸 수 있는 일반 jar만 생성

common 에는 application.yaml 파일명 사용 금지 (다른 서비스와 꼬인다.)
application-common.yaml
# actuator 설정
management:
endpoints:
web:
exposure:
# 모든 엔드포인트를 웹(HTTP)으로 노출 (개발 환경에서만 권장)
include: "*"
endpoint:
health:
show-details: always # 상세한 상태 정보 표시
env:
show-values: always
server:
tomcat:
threads:
max: 200
spring:
threads:
virtual:
enabled: true
jackson:
default-property-inclusion: non_null
application-jpa-prod.yaml
spring:
jpa:
database: mysql
properties:
hibernate:
jdbc:
batch_size: 50 # 배치작업 크기 설정
format_sql: true # 쿼리문 보기편하게 포맷팅
order_updates: true # JPA Batch 작업 활성화
show-sql: true # JPA가 쿼리문 로그에 출력
container - settings.gradle
rootProject.name = 'container'
include 'common'
gradle Sync All(코끼리 아이콘 클릭)을 하면 Gradle창에 container 아래에 common이 나타난다.


common 프로젝트를 복사(Ctrl + c) 후 붙여넣기(Ctrl + v) 하고 이름 작성이 나타나면 원하는 이름을 작성하고 붙여넣기 한다.
gateway-service
application.yaml
management:
endpoint:
gateway:
enabled: true
spring:
application:
name: gateway-service
config:
import:
- optional:classpath:application-common.yaml
cloud:
gateway:
# 4.0.x 버전 Servlet Gateway의 핵심 설정 프리픽스
server:
webmvc:
actuator:
enabled: true
cors:
configurations:
'[/**]':
allowed-origins: [ "http://localhost:5173" ]
allowed-methods: [ "GET", "POST", "PUT", "DELETE", "OPTIONS" ]
allowed-headers: [ "*" ]
allow-credentials: true
max-age: 3600
# 라우팅 설정
routes:
- id: user-service
uri: http://localhost:8080 # User Service 실제 포트 확인 필수
predicates:
- Path=/api/user/**
- id: store-service
uri: http://localhost:8081
predicates:
- Path=/api/store/**
- id: order-service
uri: http://localhost:8082
predicates:
- Path=/api/order/**
server:
port: 8000
auth-service
application.yaml
server:
port: 8080
spring:
config:
import:
- optional:classpath:application-common.yaml
application:
name: auth-service
datasource:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mysql://localhost:3306/eats_user?createDatabaseIfNotExist=true&characterEncoding=UTF-8
username: root
password: green502
jpa:
hibernate:
ddl-auto: update
build.gradle
dependencies {
// 1. 공통 모듈 의존성 주입 (가장 중요)
implementation project(':common')
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
// JSON 처리를 위한 Jackson
implementation 'io.jsonwebtoken:jjwt-api:0.13.0'
implementation 'io.jsonwebtoken:jjwt-impl:0.13.0'
implementation 'io.jsonwebtoken:jjwt-jackson:0.13.0'
// TSID 사용을 위한 유틸리티
implementation 'io.hypersistence:hypersistence-utils-hibernate-70:3.15.2'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
implementation 'org.springframework.boot:spring-boot-starter-validation'
runtimeOnly 'com.mysql:mysql-connector-j'
testImplementation 'org.springframework.boot:spring-boot-starter-data-jpa-test'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'net.datafaker:datafaker:2.5.4'
}
tasks.named('test') {
useJUnitPlatform() // 이 설정이 없으면 JUnit 5 테스트를 인식하지 못합니다.
}
// 서비스 모듈은 실행 가능한 jar 파일로 빌드되어야 합니다.
bootJar {
enabled = true
}
jar {
enabled = false // 실행 jar가 우선이므로 일반 jar는 끕니다.
}