1. ๊ฐ์
์์ ์ ๋ดค๋ Spring Cloud ๊ฐ์๋ฅผ ๋ณต์ตํ๋ฉฐ ์ด๋ฒคํธ ์คํธ๋ฆฌ๋ฐ, SAGA ํจํด, CQRS ๋ฑ MSA์ ์ฌ์ฉ๋๋ ์ฌ๋ฌ ๊ธฐ์ ๋ค์ ์ตํ๊ธฐ ์ํด ๊ฐ๋จํ ํ๋ก์ ํธ๋ฅผ ๋ง๋ค๊ณ ํ์ตํ๊ณ ์์๋ค.
์ฒ์ multi module์ ๊ณต๋ถํด์ผ๊ฒ ๋ค ํ๋ ๊ฑด kafka ๊ด๋ จ ์ค์ ๊ณผ ์ด๋ฒคํธ ํต์ ์ ์ํ dto๋ค์ ์ฝ๋ ์ค๋ณต ๋๋ฌธ์ด์๋ค. MSA ํ๊ฒฝ์ ๊ตฌ์ฑํ๋ฉด์๋ ์ฝ๋๊ฐ ์ค๋ณต๋๋ค๋๊ฒ ๋ง์ด ๋๊ปด์ก๊ณ ๊ณตํต ๋ชจ๋๋ก ๋นผ๊ณ ์ถ๋ค๋ ์๊ฐ์ด ๋ค์๋ค.
๋ํ JWT ํ ํฐ์ ์ฌ์ฉํ์ฌ ์ธ์ฆ, ์ธ๊ฐ ์ฒ๋ฆฌ๋ฅผ ํ๊ณ ์์๊ธฐ ๋๋ฌธ์ ์ ๋ก์ง๋ ์ด๋๋ก ๋นผ์ผํ ์ง ๊ณ ๋ฏผ์ด ๋์๋ค.
์ ๋ง ์์ ์ multi module์ ๋ํด์ ๊ฐ์๋ฅผ ๋ณธ ์ ์ด ์๋๋ฐ, ๊ทธ ๋ ์ด๋ฐ๊ฒ ์๊ตฌ๋ ํ๊ณ ๋์ด๊ฐ์ง๋ง ์ด๋ฒ์ ์ ๋๋ก ์์๋ณด๊ณ multi module๋ก msa ํ๊ฒฝ์ ๊ตฌ์ฑํด๋ณด๋ ค ํ๋ค.
2. ๋ฉํฐ ๋ชจ๋
โ ๋ชจ๋
Oracle Java ๋ฌธ์์์ ๋ชจ๋์ด๋ ํจํค์ง์ ํ ๋จ๊ณ ์์ ์งํฉ์ฒด์ด๋ฉฐ, ๊ด๋ จ๋ ํจํค์ง์ ๋ฆฌ์์ค๋ค์ ์ฌ์ฌ์ฉํ ์ ์๋ ๊ทธ๋ฃน์ด๋ผ๊ณ ์ ์ํ๊ณ ์๋ค.
์ด๋ ๊ฐ ๋ชจ๋์ ๋
๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐ, ๋น๋, ํ
์คํธ, ๋ฐฐํฌ๊ฐ ๊ฐ๋ฅํ๋ค.
โ ๋ฉํฐ ๋ชจ๋
๋ฉํฐ ๋ชจ๋์ ์์์ ์ธ๊ธํ ๋ชจ๋๋ค์ ํ๋์ ํ๋ก์ ํธ ์์์ ๊ด๋ฆฌํ๋ ๊ฒ์ ์๋ฏธํ๋ค.
๋ฉํฐ ๋ชจ๋ ์์์ ๊ฐ๊ฐ์ ๋ชจ๋์ ์๋ก๋ฅผ ํฅํ ์์กด์ฑ์ ๊ฐ์ง ์ ์๋ค.
์ฌ๋ฌ๊ฐ์ ๋ชจ๋์ ์์ฑํ ๋ ๋ฐ๋์ ๋ฉํฐ ๋ชจ๋ ํ๋ก์ ํธ๋ฅผ ์์ฑํด์ผํ์ง ์์ง๋ง ์ฝ๋ ์ค๋ณต ์ ๊ฑฐ, ๋ชจ๋๊ฐ ์์กด์ฑ์ ์ํด ์ ์ฅ์์ ๋ฐฐํฌํ์ง ์์๋ ๋๋ ์ ๋ฑ ์ฅ์ ์ด ์๋ค.
ํ์ ์์คํ ์ ์๋ก ๋ค์ด๋ณด์.
ํ์ ์์คํ ์๋ ๋ค์๊ณผ ๊ฐ์ ๋ ๋ฆฝ์ ์ธ ํ๋ก์ ํธ ๋จ์๊ฐ ์๋ค.
- member internal api : ๋ด๋ถ์ ๊ด๋ฆฌ์ ํ์ด์ง์์ ํธ์ถํ๋ api ์๋ฒ
- member external api : ๊ณ ๊ฐ ํ๋ฉด์์ ํธ์ถํ๋ api ์๋ฒ
- member batch : ์ฃผ๊ธฐ์ ์ธ ์์ ์ ์ํํ๋ ์๋ฒ
[ ๋จ์ผ ๋ชจ๋๋ก ๊ตฌ์ฑ๋ ๋ฉํฐ ํ๋ก์ ํธ ]
3๊ฐ์ง ํ๋ก์ ํธ ๋ชจ๋ ์ ์ ๋ผ๋ ๋์ผํ ๋๋ฉ์ธ์ ๋ํด์ ๊ตฌ์ฑํ๊ณ ์๊ธฐ ๋๋ฌธ์ ์ค๋ณต ์ฝ๋๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค. (ex. Member ๋๋ฉ์ธ ๋ชจ๋ธ)
๊ทธ๋ฐ๋ฐ ๋ง์ฝ์ ์ด๋ฌํ ์ค๋ณต ์ฝ๋์ ์์ ์ฌํญ์ด ์๊ธด๋ค๋ฉด ์ธ ๋ชจ๋์ ์ฝ๋๋ฅผ ์์ ํด์ผ ํ๊ณ ์ ์ง๋ณด์ ๋์ด๋๊ฐ ์ฌ๋ผ๊ฐ ๊ฒ์ด๋ค.
[ ๋ฉํฐ ๋ชจ๋๋ก ๊ตฌ์ฑ๋ ๋จ์ผ ํ๋ก์ ํธ ]
์์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ณ ์ ๋จ์ผ ํ๋ก์ ํธ ๋ด์์ ์ฌ๋ฌ ๊ฐ์ ๋ชจ๋์ ๊ฐ์ง ์ ์๋ ๊ตฌ์กฐ๊ฐ ๋์๋ค.
์ ๊ทธ๋ฆผ์ฒ๋ผ ํ๋์ ํ๋ก์ ํธ ๋ด์์ ๊ธฐ์กด์ ํ๋ก์ ํธ ๋จ์๋ ๋ชจ๋์ด ๋์๊ณ , ๊ณตํต๋ ์ฝ๋(common)๋ ๋ถ๋ฆฌํด์ ํจ๊ป ์ฌ์ฉํ ์ ์๋ค.
3. ๋ฉํฐ ๋ชจ๋ & DDD & MSA
๋ฉํฐ ๋ชจ๋์ ์์์ ์ธ๊ธํ์ผ๋ DDD, MSA์ ๊ฐ ๊ฐ๋ ๋ค๋ถํฐ ๊ฐ๋จํ๊ฒ ์ง๊ณ ๋์ด๊ฐ๋ฉด
MSA ๋?
MSA๋ ์์คํ ์ ๋ ๋ฆฝ์ ์ธ ๋ง์ดํฌ๋ก์๋น์ค๋ก ๋ถ๋ฆฌํ๋ ์ํคํ ์ฒ์ด๋ค. ๊ฐ ์๋น์ค๋ ๋ ๋ฆฝ์ ์ผ๋ก ๊ฐ๋ฐ, ๋ฐฐํฌ, ํ์ฅ ๊ฐ๋ฅํ๋ฉฐ ํน์ ๋๋ฉ์ธ์ ์ด์ ์ ๋ง์ถ์ด ์ค๊ณ๋๋ค. MSA๋ ๋ณต์กํ ์์คํ ์์ ์๋น์ค ๊ฐ์ ์ฐ๊ด์ฑ์ ์ต์ํํ๊ณ ๋ ๋ฆฝ์ ์ธ ์๋น์ค๋ก ๊ตฌ์ฑ๋๋๋ก ํ์ฌ, ์์คํ ์ ์ ์ง๋ณด์์ ํ์ฅ์ฑ์ ๋์ด๋ ๋ฐ ์ ๋ฆฌํ๋ค
DDD ๋?
DDD๋ ๋๋ฉ์ธ ์ง์์ ๋ฐ์ํ ๋ชจ๋ธ๋ง์ ํตํด ๋ณต์กํ ๋น์ฆ๋์ค ๋ก์ง์ ๊ด๋ฆฌํ๋ ์ค๊ณ ๋ฐฉ์์ด๋ค. ํต์ฌ ๋น์ฆ๋์ค ๋๋ฉ์ธ์ ์๋ณํ๊ณ ์ด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ชจ๋ธ์ ์ค์ฌ์ผ๋ก ์์คํ ์ ๊ตฌ์ถํ๋ค. DDD ์ค๊ณ๋ฅผ ํตํด ๊ฐ ๋ง์ดํฌ๋ก ์๋น์ค๋ค์ ์๋น์ค ๊ฐ ์์กด์ฑ์ ๋ฎ์ถ๊ณ ๋ ๋ฆฝ์ ์ธ ๋ฐฐํฌ์ ๊ฐ๋ฐ์ด ๊ฐ๋ฅํ๊ฒ ๋ง๋ ๋ค.
์ ์ธ ๊ฐ์ง๋ ์๋ก ๋ณด์์ ์ด๋ฉฐ ๊ฐ์์ ์ฅ์ ๋ค์ ํฉ์ณ ์ ์ฐํ๊ณ ํ์ฅ ๊ฐ๋ฅํ ์์คํ ์ ๊ตฌ์ถํ ์ ์๋ค.
์๋ฅผ ๋ค์ด, DDD(๋๋ฉ์ธ ์ฃผ๋ ์ค๊ณ)๋ก ์์คํ ์ ๋๋ฉ์ธ ์ค์ฌ์ผ๋ก ์ค๊ณํ์ฌ ๋น์ฆ๋์ค ๋ก์ง์ ๋ช ํํ ๊ตฌ๋ถํ ํ, MSA ์ํคํ ์ฒ๋ก ์์คํ ์ ๊ตฌ์ฑํ ์ ์๋ค. ๊ฐ ๋๋ฉ์ธ์ ๋ ๋ฆฝ์ ์ธ ๋ง์ดํฌ๋ก์๋น์ค๋ก ๋ถ๋ฆฌํจ์ผ๋ก์จ ์์คํ ์ ๊ฒฐํฉ๋๋ฅผ ๋ฎ์ถ๊ณ ๋ ๋ฆฝ์ ์ผ๋ก ๋ฐฐํฌ ๋ฐ ํ์ฅ์ด ๊ฐ๋ฅํ๋ค.
๋ํ, MSA๋ ๋ ๋ฆฝ์ ์ธ ๋ง์ดํฌ๋ก์๋น์ค๋ฅผ ์ฌ๋ฌ ๊ฐ ์ด์ํ๋ ๋ฐฉ์์ด๋ฏ๋ก, ๊ณตํต์ผ๋ก ํ์ํ ๊ธฐ๋ฅ(์: ์ธ์ฆ, ๋ก๊น , ์์ธ ์ฒ๋ฆฌ ๋ฑ)์ด ์ฌ๋ฌ ์๋น์ค์์ ๋ฐ๋ณต์ ์ผ๋ก ๊ตฌํ๋์ด์ผ ํ๋ ๊ฒฝ์ฐ๊ฐ ๋ฐ์ํ ์ ์๋ค. ์คํ๋ง ๋ฉํฐ๋ชจ๋์ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ๊ณตํต ๊ธฐ๋ฅ์ common ๋ชจ๋๋ก ์ถ์ถํ์ฌ ์ฌ์ฌ์ฉํ ์ ์๋ค.
MSA์ ๋ฉํฐ๋ชจ๋์ ๊ฒฐํฉ์ ๊ฐ ๋ง์ดํฌ๋ก์๋น์ค๊ฐ ํ์ํ ๊ธฐ๋ฅ๋ง ์ฐธ์กฐํ ์ ์๊ฒ ํ์ฌ ์ํคํ ์ฒ์ ์ ์ฐ์ฑ์ ์ ์งํ๋ฉด์๋ ๋ฐ๋ณต๋๋ ์ฝ๋ ์์ฑ์ ์ต์ํํ ์ ์๊ฒ ํ๋ค.
4. Spring Boot ์์ ๋ฉํฐ ๋ชจ๋ ์ ์ฉํ๊ธฐ
๋ค์ด๊ฐ๊ธฐ ์์ ํจํค์ง ๊ตฌ์กฐ๋ ์๋์ ๊ฐ์ด ๊ฐ์ ธ๊ฐ๋ค.
Spring Cloud ๊ด๋ จ ๋ชจ๋์ธ api gateway, eureka ๊ฐ ์๊ณ , ์์ ์ ๋ง๋ค์ด๋๋ todo ์ ํ๋ฆฌ์ผ์ด์ ์ member ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค. temp-server๋ ๊ทธ๋ฅ micro server ๊ฐ์๋ฅผ ๋๋ฆฌ๊ธฐ ์ํด ๋ง๋ค์ด ๋ณด์๋ค.. ใ ใ
common์ ๊ณตํต ๋ชจ๋ ์ญํ ์ ํ๊ณ infra๋ kafka, zipkin ๋ฑ์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋์ฐ๋ ๋ฐ ํ์ํ docker ๊ด๋ จ ์ค์ ์ ํด๋์๋ค.
๐ฆspring-cloud-test
โฃ ๐apigateway
โฃ ๐common
โฃ ๐eureka
โฃ ๐gradle
โฃ ๐infra
โฃ ๐member-server
โฃ ๐temp-server
โฃ ๐todo-app-server
โฃ ๐.gitattributes
โฃ ๐.gitignore
โฃ ๐build.gradle
โฃ ๐gradlew
โฃ ๐gradlew.bat
โฃ ๐HELP.md
โ ๐settings.gradle
๋ฃจํธ ๋ชจ๋ ์์ฑ
๋ฉํฐ ๋ชจ๋์ ์ ๋ถ ๊ด๋ฆฌํ ๋ฃจํธ ๋ชจ๋์ ์์ฑํ ํ src ๋๋ ํ ๋ฆฌ๋ ์ญ์ ํด์ค๋ค.
src ๋๋ ํ ๋ฆฌ๊ฐ ๋จ์์์ ๊ฒฝ์ฐ ์๋์ ๊ฐ์ ์๋ฌ์ ๋ง์ฃผ์น๊ฒ ๋ ๊ฒ์ด๋ค.
Execution failed for task ':bootRun'.
> Failed to calculate the value of task ':bootRun' property 'mainClass'.
> Main class name has not been configured and it could not be resolved
* 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.
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0.
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins.
For more on this, please refer to https://docs.gradle.org/8.4/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation.
BUILD FAILED in 1s
3 actionable tasks: 2 executed, 1 up-to-date
ํ์ ๋ชจ๋ ์์ฑ
ํ์ ๋ชจ๋ ์ญํ ์ ํ ์๋ก์ด ๋ชจ๋ ์์ฑ์ ์ธํ ๋ฆฌ์ ์ด์์ ๊ฐ๋จํ๊ฒ ํ ์ ์๋ค. ๋ง์ฝ ์ ์ฒด ๋ชจ๋์์ ๊ณตํต์ ์ผ๋ก ์ฌ์ฉํ ๋ํ๋์๊ฐ ์๋ค๋ฉด ๋ฃจํธ ๋ชจ๋์์ ์ฃผ์ ํด์ฃผ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๋ณธ์ธ์ ๋ชจ๋์์๋ง ์ฌ์ฉํ ์์กด์ฑ๋ง ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
์์ฑ ํ ์๋ ํ์ผ๋ค์ ์ ๋ถ ์ง์์ฃผ์.
์ฝ์ง์ ์ข ํ๋ ๋ถ๋ถ์ธ๋ฐ, gradle ๊ด๋ จ ํ์ผ์ด ํ์ ๋ชจ๋์ ๋จ์์์ผ๋ฉด gradle build๋ฅผ ์งํํ ๋ ํ์ ๋ชจ๋๋ ๋ฐ๋ก ๋งํฌ๋ฅผ ๋งบ๊ฒ ๋๊ณ ๋ฃจํธ ๋ชจ๋์์ ๊ด๋ฆฌํ ์ ์๋ค.
์ฒ์ ๋ชจ๋์ ์์ฑํ๊ณ ๋ ํ์ build.gradle์ ๋ชจ์ต์ด๋ค.
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
์ฌ๊ธฐ์ dependencies๋ง ๋จ๊ฒจ๋๊ณ ์ ๋ถ ์ง์์ฃผ์. (๋ฃจํธ ๋ชจ๋๋ก๋ถํฐ ์ฃผ์ ๋ฐ์ ๋ด์ฉ์ ์ ์ธํ๊ธฐ ์ํจ, ์์ด๋ ๋ฌธ์ ์์ง๋ง ์ฝ๋ ์ค๋ณต)
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
๋ฃจํธ ๋ชจ๋์์ build.gradle ์ค์
plugins {
id 'java'
id 'org.springframework.boot' version '3.3.5'
id 'io.spring.dependency-management' version '1.1.6'
}
bootJar.enabled = false // ๋ฃจํธ ํ๋ก์ ํธ์ bootJar ๋นํ์ฑํ
subprojects {
group = 'com.example'
version = '0.0.1-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
bootJar.enabled = true
jar.enabled = false
tasks.named('test') {
useJUnitPlatform()
}
ext {
set('springCloudVersion', "2023.0.3")
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
// ๊ณตํต์ผ๋ก ์ฌ์ฉํ ์์กด์ฑ ์ถ๊ฐ
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
}
ํ์ ๋ชจ๋์ ์ฃผ์ ํ ๋ด์ฉ๋ค์ subprojects {} ์์ ๋ฃ์ด์ค๋ค.
์คํ ๋ชฉ์ ์ ๊ฐ์ง ํ์ ๋ชจ๋์ bootJar๋ง ํ์ฑํ ํ๊ณ Jar๋ ๋นํ์ฑํ ํด์ค๋ค.
ํ์ง๋ง common ๋ชจ๋ ๊ฐ์ด ๋ค๋ฅธ ๋ชจ๋์์ ๊ณต์ ํด์ผ ํ๋ ๊ฒฝ์ฐ๋ผ๋ฉด BooJar๋ฅผ ๋นํ์ฑํ ํ๊ณ Jar๋ ํ์ฑํ ํด์ค๋ค.
project(':common') {
bootJar { enabled = false } // ๊ณตํต ๋ชจ๋์ bootJar ๋ก ํจํค์ง ํ ํ์ ์์
jar { enabled = true }
dependencies {
}
}
์ด๋ ๊ฒ ๋ฃจํธ ๋ชจ๋์์ ํ์ ๋ชจ๋์ ํน์ ํด์ gradle ์ค์ ์ ํด์ค ์๋ ์๊ณ , common ๋ชจ๋์ build.gradle ํ์ผ์์ ์ง์ ์ค์ ํ ์ ์๋ค.
๋ฃจํธ ๋ชจ๋์ setting.gradle ์ค์
rootProject.name = [๋ฃจํธ ๋ชจ๋]
include [ํ์ ๋ชจ๋1]
include [ํ์ ๋ชจ๋2]
include [ํ์ ๋ชจ๋3]
include [ํ์ ๋ชจ๋4]
include [ํ์ ๋ชจ๋5]
...
๋ฃจํธ ๋ชจ๋์์ ์ค์ ํ build.gradle ํ์ผ์ ์ฃผ์ ํ ๋ชจ๋ ๋ค์ include ํด์ฃผ๋ฉด spring boot์์ multi module ์ค์ ์ด ๋์ด๋๋ค.
์ดํ gradle refresh๋ฅผ ๋๋ ค๋ณด๋ฉด ์๋ ์ฒ๋ผ ๋ฃจํธ ๋ชจ๋ ํ๋๋ง ๋จ๊ณ ๊ทธ ์๋์ ํ์ ๋ชจ๋์ด ๋ ์ผํ๋ค.
์์์ ์ฌ๋ฌ ๊ฐ๊ฐ ๋ฌ๋ค๋ฉด ์ค์ ์ด ์๋ชป๋ ๊ฒฝ์ฐ์ด๋ค.
์ด๋ ๊ฒ ๊ตฌ์ฑ์ด ๋๋ค๋ฉด ๋ชจ๋๋ค์ ์ด๋ ๊ฒ ๋ชจ์์ ๋ณผ ์ ์๊ณ ๋ณต์ ์ ํ ํ ํ๋ฒ์ ์คํ๋ ๊ฐ๋ฅํ๋ค. ๋๋ฌด ํธํ ๊ฒ... ๐