ํ์ : ๊ฐ์ธ ํ๋ก์ ํธ
๊ธฐ๊ฐ : 2025.01 ~ ์งํ ์ค
๋งํฌ : https://github.com/M-ung/TicToc_Server
์๋น์ค ๋ด์ฉ : ๋น์ ์ ์๊ฐ์ ๊ฐ์น๋ฅผ ๋งค๊ธฐ๋ค, ์๊ฐ ๊ฑฐ๋ ๊ฒฝ๋งค ํ๋ซํผ
์ด๊ธฐ ๊ฐ๋ฐ ๋จ๊ณ์์๋ ๋ ํ๋๋๋ก ํ๋ก์ ํธ๋ฅผ ๋จ์ผ๋ชจ๋๋ก ๊ตฌ์ฑํ๊ณ , ํฌ๊ฒ domain๊ณผ global๋ก ๋๋ ํ ๋ฆฌ๋ฅผ ๋๋๊ณ ๋ ์ด์ด๋ ์ํคํ ์ฒ๋ก ์ ์ฉํ๋ค. ํ์ง๋ง ๊ฐ์ธ ํ๋ก์ ํธ๋ก์ ์ฅ๊ธฐ์ ์ผ๋ก ์ง์์ ์ธ ๊ฐ๋ฐ์ด ํ์ํ๊ธฐ ๋๋ฌธ์ ๋ค์๊ณผ ๊ฐ์ ๋ฌธ์ ์ ์ด ๋ฐ์ํ๋ค.
1. ์ ์ง๋ณด์์ ํ์ฅ์ฑ์ ์ด๋ ค์
2. ๋ฐฐํฌํ ๋ ๋น๋ ์๋ ์ ํ
3. ํ
์คํธ ์ฝ๋ ์์ฑ์ ๋ถํธํจ
์ ๋ฌธ์ ๋ค์ ํด๊ฒฐํ๊ธฐ ์ํด์ ๊ธฐ์กด์ ๋จ์ผ๋ชจ๋ ํ๋ก์ ํธ๋ณด๋ค ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ๋ฉํฐ๋ชจ๋ ํ๋ก์ ํธ๋ก ๋ณ๊ฒฝํ๋ ๊ฒ์ด ์ข๋ค๊ณ ์๊ฐํ๋ค. ๊ทธ๋์ ์๋ ๋ฐฉ๋ฒ์ ์ ์ฉํ๊ธฐ๋ก ํ๋ค.
1. ํ๋ก์ ํธ ๋ฉํฐ๋ชจ๋ ์ธํ
2. ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ ์ ์ฉ
1. ํ๋ก์ ํธ ๋ฉํฐ๋ชจ๋ ์ธํ
๋จผ์ ๋จ์ผ๋ชจ๋์์ ๋ฉํฐ๋ชจ๋ ํ๋ก์ ํธ๋ก ๊ตฌ์ฑํ๊ณ , ๊ฐ ๋ชจ๋ ๊ณ์ธต์ ์๋์ ๊ฐ์ด ๊ตฌ์ฑํ๋ค.
๐ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ
tictoc-api ## ๐๏ธ API ๊ด๋ จ ๋ชจ๋
โโโ Dockerfile
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocApiApplication.java
โ โ โโโ auction
โ โ โ โโโ adapter (## ๐๏ธ API ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ปจํธ๋กค๋ฌ)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ mapper (## ๐๏ธ ๊ฐ์ฒด ๋ณํ)
โ โ โ โโโ port (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ์ธํฐํ์ด์ค)
โ โ โ โโโ application (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ๊ตฌํ์ฒด)
โ โ โโโ bid
โ โ โ โโโ adapter (## ๐๏ธ API ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ปจํธ๋กค๋ฌ)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ mapper (## ๐๏ธ ๊ฐ์ฒด ๋ณํ)
โ โ โ โโโ port (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ์ธํฐํ์ด์ค)
โ โ โ โโโ application (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ๊ตฌํ์ฒด)
โ โ โโโ user
โ โ โ โโโ adapter (## ๐๏ธ API ์์ฒญ์ ์ฒ๋ฆฌํ๋ ์ปจํธ๋กค๋ฌ)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ mapper (## ๐๏ธ ๊ฐ์ฒด ๋ณํ)
โ โ โ โโโ port (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ์ธํฐํ์ด์ค)
โ โ โ โโโ application (## ๐๏ธ ๋น์ง๋์ค ๋ก์ง ๊ตฌํ์ฒด)
โ โ โโโ config
โ โ โ โโโ CorsFilter.java
โ โ โ โโโ SpringDocOpenApiConfig.java (## ๐ Swagger)
โ โ โ โโโ WebConfig.java
โ โ โ โโโ security
โ โโโ resources
โ โ โโโ application.yml (## ๐ ๊ณตํต application.yml)
โ โ โโโ application-dev.yml (## ๐ ๊ฐ๋ฐ application.yml)
โ โ โโโ application-prod.yml (## ๐ ๋ฐฐํฌ application.yml)
tictoc-batch (## ๐๏ธ Spring Batch ๊ด๋ จ ๋ชจ๋)
โโโ Dockerfile
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocBatchApplication.java
โ โ โโโ userLoginHistory
โ โ โ โโโ config (## ๐๏ธ Spring Batch)
โ โ โ โโโ event (## ๐๏ธ Kafka Consumer)
โ โ โ โโโ scheduler (## ๐๏ธ Spring Batch Scheduler)
โ โโโ resources
โ โ โโโ application.yml (## ๐ ๊ณตํต application.yml)
โ โ โโโ application-dev.yml (## ๐ ๊ฐ๋ฐ application.yml)
โ โ โโโ application-prod.yml (## ๐ ๋ฐฐํฌ application.yml)
tictoc-common (## ๐๏ธ ๊ณตํต ๋ก์ง ๊ด๋ จ ๋ชจ๋)
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocCommonApplication.java
โ โ โโโ annotation (## ๐๏ธ ์ปค์คํ
์ด๋
ธํ
์ด์
)
โ โ โโโ aspect (## ๐๏ธ AOP)
โ โ โโโ config (## ๐๏ธ ๊ณตํต ์ค์ )
โ โ โโโ constants (## ๐๏ธ ๊ณตํต ์์)
โ โ โโโ error (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โ โโโ model (## ๐๏ธ ๊ณตํต ๊ฐ์ฒด)
โ โโโ resources
โ โ โโโ application-common.yml (## ๐ common application.yml)
tictoc-domain (## ๐๏ธ ๋๋ฉ์ธ ๊ด๋ จ ๋ชจ๋)
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocDomainApplication.java
โ โ โโโ auction
โ โ โ โโโ adapter (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ๊ตฌํ์ฒด)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ event (## ๐๏ธ Redis Event)
โ โ โ โโโ exception (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โ โโโ port (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ์ธํฐํ์ด์ค)
โ โ โ โโโ repository (## ๐๏ธ DB์ ์ ๊ทผํ๋ ์ ์ฅ์)
โ โ โโโ bid
โ โ โ โโโ adapter (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ๊ตฌํ์ฒด)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ exception (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โ โโโ port (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ์ธํฐํ์ด์ค)
โ โ โ โโโ repository (## ๐๏ธ DB์ ์ ๊ทผํ๋ ์ ์ฅ์)
โ โ โโโ config (## ๐๏ธ ๋๋ฉ์ธ ์ค์ )
โ โ โโโ notification
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โโโ payment
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โโโ propfile
โ โ โ โโโ adapter (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ๊ตฌํ์ฒด)
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โ โโโ port (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ์ธํฐํ์ด์ค)
โ โ โ โโโ repository (## ๐๏ธ DB์ ์ ๊ทผํ๋ ์ ์ฅ์)
โ โ โโโ user
โ โ โ โโโ adapter (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ๊ตฌํ์ฒด)
โ โ โ โโโ dto (## ๐๏ธ ๋ฐ์ดํฐ ์ ์ก ๊ฐ์ฒด)
โ โ โ โโโ exception (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โ โ โโโ model (## ๐๏ธ ๋๋ฉ์ธ ์ํฐํฐ)
โ โ โ โโโ port (## ๐๏ธ DB์ ์ฐ๊ฒฐํ๋ ์ธํฐํ์ด์ค)
โ โ โ โโโ repository (## ๐๏ธ DB์ ์ ๊ทผํ๋ ์ ์ฅ์)
โ โโโ resources
โ โ โโโ application-domain.yml (## ๐ domain application.yml)
tictoc-external (## ๐๏ธ ์๋ถ ๋ก์ง ๊ด๋ จ ๋ชจ๋)
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocExternalApplication.java
โ โ โ โโโ config (## ๐๏ธ openFeign ์ค์ )
โ โ โโโ kakao (## ๐๏ธ Kakao ์ฐ๊ฒฐ)
โ โโโ resources
โ โ โโโ application-external.yml (## ๐ external application.yml)
tictoc-infrastructure (## ๐๏ธ Redis, Kafka ๊ด๋ จ ๋ชจ๋)
โโโ build.gradle
โโโ src
โโโ main
โ โโโ java
โ โ โโโ tictoc
โ โ โโโ TicTocInfrastructureApplication.java
โ โ โโโ kafka
โ โ โ โโโ config (## ๐๏ธ Kafka ์ค์ )
โ โ โ โโโ event (## ๐๏ธ Kafka Producer)
โ โ โ โโโ exception (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โ โโโ redis
โ โ โ โโโ auction
โ โ โ โ โโโ adapter (## ๐๏ธ Redis ๋น์ง๋์ค ๋ก์ง ๊ตฌํ์ฒด)
โ โ โ โ โโโ port (## ๐๏ธ Redis ๋น์ง๋์ค ๋ก์ง ์ธํฐํ์ด์ค)
โ โ โ โโโ config (## ๐๏ธ Redis ์ค์ )
โ โ โ โโโ exception (## ๐๏ธ ์ปค์คํ
์๋ฌ)
โ โโโ resources
โ โ โโโ application-infrastructure.yml (## ๐ infrastructure application.yml)
๊ทธ๋ฆฌ๊ณ ๊ฐ ๋ชจ๋์ด ์ ์์ ์ผ๋ก ๋์๊ฐ ์ ์๊ฒ settings.gradle
์ ์๋์ ๊ฐ์ด ์์ฑํ๋ค.
๐ settings.gradle
rootProject.name = 'TicToc'
include 'tictoc-common'
include 'tictoc-api'
include 'tictoc-domain'
include 'tictoc-infrastructure'
include 'tictoc-batch'
include 'tictoc-external'
๋ tictoc-api
์ tictoc-batch
๋ ์ ํ๋ฆฌ์ผ์ด์
์ ๋์์ํฌ ๋ชจ๋์ด๊ณ tictoc-domain
, tictoc-common
, tictoc-external
, tictoc-infrastructure
์ ์์กดํ ๋ชจ๋์ด๊ธฐ์ ์๋์ ๊ฐ์ด build.gradle
์ ์์ฑํ๋ค.
๐ tictoc-api build.gradle
bootJar {
archiveBaseName = "app"
archiveVersion = ""
}
processResources {
from(project(":tictoc-common").file("src/main/resources")) {
into("BOOT-INF/classes")
}
from(project(":tictoc-domain").file("src/main/resources")) {
into("BOOT-INF/classes")
}
from(project(":tictoc-infrastructure").file("src/main/resources")) {
into("BOOT-INF/classes")
}
from(project(":tictoc-external").file("src/main/resources")) {
into("BOOT-INF/classes")
}
}
jar {
enabled = false
}
dependencies {
implementation project(':tictoc-common')
implementation project(':tictoc-domain')
implementation project(':tictoc-infrastructure')
implementation project(':tictoc-external')
// Swagger
implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.1.0'
implementation 'javax.servlet:javax.servlet-api:4.0.1'
//security
implementation 'org.springframework.boot:spring-boot-starter-validation'
implementation 'org.springframework.boot:spring-boot-starter-security'
testImplementation 'org.springframework.security:spring-security-test'
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
implementation group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
implementation group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
// mapstruct
implementation 'org.mapstruct:mapstruct:1.5.5.Final'
annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final'
}
๐ tictoc-batch build.gradle
bootJar {
archiveBaseName = "app"
archiveVersion = ""
}
processResources {
from(project(":tictoc-domain").file("src/main/resources")) {
into("BOOT-INF/classes")
}
}
jar {
enabled = false
}
dependencies {
// Spring Batch
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.batch:spring-batch-core'
implementation project(':tictoc-domain')
implementation project(':tictoc-common')
implementation project(':tictoc-infrastructure')
}
๐ tictoc-domain build.gradle
bootJar.enabled = false
jar.enabled = true
dependencies {
implementation project(':tictoc-common')
implementation project(':tictoc-infrastructure')
// mysql
runtimeOnly 'com.mysql:mysql-connector-j'
}
def generated = layout.buildDirectory.dir("generated/querydsl")
sourceSets {
main {
java {
srcDirs += generated
}
}
}
clean.doLast {
file(generated).deleteDir()
}
๐ tictoc-common build.gradle
bootJar.enabled = false
jar.enabled = true
dependencies {
}
๐ tictoc-external build.gradle
bootJar.enabled = false
jar.enabled = true
dependencies {
implementation project(':tictoc-common')
}
๐ tictoc-infrastructure build.gradle
bootJar.enabled = false
jar.enabled = true
dependencies {
implementation project(':tictoc-common')
// redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}
๋ง์ง๋ง์ผ๋ก ๊ฐ ๋ชจ๋์ ์ญํ ์ ๋ง๊ฒ application.yml ํ์ผ์ ์๋์ ๊ฐ์ด ์์ฑํ๋ค.
๐ application.yml (tictoc-api)
jwt:
secret: ${JWT_SECRET}
accessTokenExpireTime: ${JWT_ACCESS_EXPIRE_TIME}
refreshTokenExpireTime: ${JWT_REFRESH_EXPIRE_TIME}
server:
port: 8080
tomcat:
threads:
max: 200
min-spare: 10
accept-count: 100
spring:
jpa:
database-platform: org.hibernate.dialect.MySQL8Dialect
hibernate:
ddl-auto: update
properties:
hibernate:
format_sql: true
show_sql: false
profiles:
active: dev
include:
- domain
- external
- infrastructure
config:
import: optional:file:.env[.properties]
threads:
virtual:
enabled: true
servlet:
multipart:
max-file-size: 5MB
logging.level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace
org.springframework.web.cors: DEBUG
๐ application.yml (tictoc-batch)
jwt:
secret: ${JWT_SECRET}
accessTokenExpireTime: ${JWT_ACCESS_EXPIRE_TIME}
refreshTokenExpireTime: ${JWT_REFRESH_EXPIRE_TIME}
server:
port: 8081
tomcat:
threads:
max: 200
min-spare: 10
accept-count: 100
spring:
profiles:
active: dev
include:
- domain
- external
- infrastructure
config:
import: optional:file:.env[.properties]
batch:
jdbc:
initialize-schema: always
threads:
virtual:
enabled: true
servlet:
multipart:
max-file-size: 5MB
logging.level:
org.hibernate.SQL: debug
org.hibernate.orm.jdbc.bind: trace
org.springframework.web.cors: DEBUG
๐ application-domain.yml
spring:
datasource:
master:
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${DB_HOST}:${MASTER_DB_PORT}/${DB_NAME}?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: ${DB_USER}
password: ${DB_PASSWORD}
slave:
hikari:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://${DB_HOST}:${SLAVE_DB_PORT}/${DB_NAME}?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=Asia/Seoul&characterEncoding=UTF-8
username: ${DB_USER}
password: ${DB_PASSWORD}
๐ application-external.yml
feign:
kakao:
kakao_get_token_name: ${KAKAO_GET_TOKEN_NAME}
kakao_get_profile_name: ${KAKAO_GET_PROFILE_NAME}
kakao_get_token_info_name: ${KAKAO_GET_TOKEN_INFO_NAME}
get-kauth-url: ${KAKAO_KAUTH_URL}
get-kapi-url: ${KAKAO_KAPI_URL}
redirect: ${KAKAO_REDIRECT}
rest-api-key: ${KAKAO_REST_API_KEY}
๐ application-infrastructure.yml
spring:
cache:
type: redis
data:
redis:
host: ${REDIS_HOST}
port: ${REDIS_PORT}
kafka:
bootstrap-servers: ${KAFKA_HOST}:${KAFKA_PORT}
producer:
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
listener:
type: ${KAFKA_TYPE}
consumer:
group-id: ${KAFKA_GROUP}
auto-offset-reset: latest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
2. ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ ์ ์ฉ
์์ ์ ์ ๋๋ ํ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ๋ฅผ ํ์ฉํ ๊ฒ์ ์ ์ ์๋ค. ์ํคํ
์ฒ ๊ตฌ์กฐ๋ ์๋์ ๊ฐ๋ค.
ํด๋ผ์ด์ธํธ๊ฐ ์์ฒญ์ ๋ณด๋ด๋ฉด, ๋จผ์ tictoc-api ๋ชจ๋์ Controller ๊ณ์ธต์์ ์ด๋ฅผ ์์ ํ๋ค. ๊ทธ ๋ค์, ๋น์ฆ๋์ค ๋ก์ง์ ์ธํฐํ์ด์ค ๊ณ์ธต์ธ UseCase๋ฅผ ํตํด ์์ฒญ์ด ์ ๋ฌ๋๋ฉฐ, ํด๋น ์์ฒญ์ ๊ตฌํ์ฒด์ธ Service ๊ณ์ธต์์ ์ฒ๋ฆฌ๋๋ค.
๋น์ฆ๋์ค ๋ก์ง ๊ณผ์ ์์ ๋๋ฉ์ธ ๊ฐ์ฒด ๋ฐ DB ์ ๊ทผ์ด ํ์ํ ๊ฒฝ์ฐ, tictoc-domain ๋ชจ๋์ Port ์ธํฐํ์ด์ค๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ค. ๊ทธ ๋ค์, Port ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด์ธ Adaptor๋ Repository๋ฅผ ํ์ฉํ์ฌ DB์ ์ ๊ทผํ์ฌ ์ํํ๋ ํ๋ฆ์ด๋ค.
์ ์ฌ์ง์ ๋ณด๋ฉด DB๊ฐ Master์ Slave๋ก ๋๋ ์ ธ ์๊ณ , Query์ Command๋ผ๋ ๋จ์ด๊ฐ ๋ณด์ธ๋ค. ์ด๋ ๋ค์ ๊ธ์์ ์์ธํ ๋ค๋ฃจ๊ฒ ์ง๋ง, ์ดํด๋ฅผ ๋๊ธฐ ์ํด ๊ฐ๋จํ ์ค๋ช ํ๊ฒ ๋ค.
Query์ Command๋ฅผ ๋๋๋ ๊ธฐ์ค์ ํฌ๊ฒ ์ญํ ์ด "์ฐ๊ธฐ"๋ "์ฝ๊ธฐ"๋์ ๋ฐ๋ผ ๊ฒฐ์ ํ๋ค. ์ด๋ ๊ฒ ํ๋ ์ด์ ๋ CQRSํจํด, DB๋ถ๋ฆฌ, ์๋ ๊ฐ์ , ๋ฑ ์ฌ๋ฌ ์ด์ ๊ฐ ์๊ฒ ์ง๋ง, ์ ๋ ํ๋ก์ ํธ๋ฅผ ์ต๋ํ ๋ชจ๋ํํ๊ณ ์ถ๊ณ ๊ฐ์ฒด๋ฅผ ์ญํ ๋ณ๋ก ๊น๋ํ๊ฒ ๊ด๋ฆฌํ๊ณ ์ถ์ด์ ์ ๋ค์ด๋ฐ ๋ฒ์น์ ๊ฐ์ ธ์ค๊ณ ์๋ค.
๊ทธ๋ฆฌ๊ณ ์ด๋ฒ ํ๋ก์ ํธ์์๋ DB๋ฅผ Mysql์ ์ฌ์ฉํ๊ณ ์๋๋ฐ, ์ด๋ฅผ Master์ Slave๋ก ๋๋ ์ ์ ์ํคํ
์ฒ ๊ทธ๋ฆผ๋๋ก ๊ด๋ฆฌํ ์์ ์ด๋ค.
๋ฌธ์ ํด๊ฒฐ๋ก ์๋์ ๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ์ป์๋ค.
1. ์ ์ง๋ณด์์ฑ ๋ฐ ํ์ฅ์ฑ ํฅ์.
2. ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ฐ์ดํฐ ์ ๊ทผ ๋ก์ง ๋ถ๋ฆฌ.
์ต์ข
ํ๋ก์ ํธ ๋ชจ๋ ํํ๋ ์๋์ ๊ฐ๋ค.
๋ "๊ฒฝ๋งค ๋ฑ๋ก" ๊ธฐ๋ฅ์ ์๋์ ๊ฐ์ด ํฅ์ฌ๊ณ ๋ ์ํคํ ์ฒ๋ก ๊ตฌํํ๋ค.
๐ AuctionCommandController.java
๐ AuctionCommandUseCase.java
๐ AuctionCommandService.java
๐ AuctionRepositoryPort.java
๐ AuctionRepositoryAdapter.java
๐ AuctionRepository.java
์ด์ ๊น์ง ๋จ์ผ๋ชจ๋๋ก ๊ฐ๋ฐ์ ํด์์๊ณ ๋ฉํฐ๋ชจ๋์ด ์๋ค๋ ์ฌ์ค์ ์ด๋ฒ์ ์ฒ์ ์์๋ค. ์ด์ ๊น์ง ๋จ์ผ๋ชจ๋๋ก ๊ฐ๋ฐ์ ํ๋ฉด์ ๋๋ ํ ๋ฆฌ์ ํด๋์ค์ ๊ฐ์๊ฐ ๋์ด๋ ๋๋ง๋ค ๊ด๋ฆฌํ๊ณ ์ํ๋ ํ์ผ ์ฐพ๊ธฐ๊ฐ ์ด๋ ค์ ์๋ค.
์ด๋ฒ ๋ฉํฐ๋ชจ๋๋ก ๋ณ๊ฒฝํ ํ ๊ฐ๋ฐ์ ์ญ ๋๋ต 2๊ฐ์ ๊ฐ๊น์ด ์งํํด ๋ณด์๋๋ฐ, ํ์คํ ์ํ๋ ํ์ผ ์ฐพ๊ธฐ๊ฐ ๋จ์ผ๋ชจ๋์ผ ๋๋ณด๋ค ํจ์ฌ ์์ํด์ก๋ค.
๋ ๋ชจ๋์ ์ฌ๋ฌ ๊ฐ๋ก ๋๋ ๋์ build ์๊ฐ ๋ํ ๋จ์ถ๋ ๋๋์ด ๋ค์๋ค.
์์ผ๋ก ์ด ํ๋ก์ ํธ๋ฅผ ํ์ฅํด ๋๊ฐ๋ ๋ฐ์ ์์ด์ ํ๋ก์ ํธ๋ฅผ ๊ด๋ฆฌํ๊ธฐ ์ ๋ณด๋ค ์ด๋ ต์ง ์์ ๊ฒ ๊ฐ๋ค.
ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ๋ผ๋ ๋จ์ด ๋ํ ์ด๋ฒ์ ์ฒ์ ๋ค์ด๋ดค๋ค. ์ฒ์์๋ ํด๋ฆฐ ์ํคํ
์ฒ๋ฅผ ๋จผ์ ์๊ฒ ๋์์ด์ ์ด๋ฅผ ์ ์ฉํด ๋ณด๋ ค๊ณ ํ๋๋ฐ, ๊ตฌ๊ธ์์ ๋ํผ๋ฐ์ค๋ฅผ ์ฐพ๊ธฐ๊ฐ ์ฝ์ง ์์๋ค. ๊ทธ๋์ ํด๋ฆฐ ์ํคํ
์ฒ์์ ํ์๋ ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ๊ฐ ์๋ค๋ ์ฌ์ค์ ์๊ณ ์์๋ณด๊ฒ ๋์๊ณ , ํด๋ฆฐ ์ํคํ
์ฒ๋ณด๋ค ๋ํผ๋ฐ์ค๋ ๋ง์ด ์๊ธฐ์ ์ด๋ฅผ ํํ๋ค.
์ ์ฉํ ๊ฒฐ๊ณผ, ๋น์ฆ๋์ค ๋ก์ง์์ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์ธ๋ถ API์ ์ง์ ์์กดํ๋ ๊ฒ์ด ์๋๋ผ,
UseCase, Port์ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ํตํด์๋ง ์ ๊ทผํ ์ ์๋๋ก ์ ํํ ์ ์์๋ค. ์ด ๋๋ถ์ DB ๋ด์ฉ์ ๋ณ๊ฒฝํ ๋, ๋น์ฆ๋์ค ๋ก์ง์ ๋ณ๊ฒฝํ ํ์๊ฐ ์์ด์ง๋ ์ฅ์ ๊ณผ ์ฝ๋๊ฐ ํจ์ฌ ๊น๋ํด์ง๋ ํจ๊ณผ๋ฅผ ์ป์ ์ ์์๋ค.
๋ง์ง๋ง์ผ๋ก ํฅ์ฌ๊ณ ๋ ์ํคํ
์ฒ ์ค "๋๋ฉ์ธ๊ณผ ์ํฐํฐ"๋ฅผ ๋ถ๋ฆฌํ๋ ๋ด์ฉ์ด ์์๋ค. ๋๋ฉ์ธ๊ณผ ์ํฐํฐ๋ฅผ ๋ถ๋ฆฌํ๋ฉด ๋น์ฆ๋์ค ๋ก์ง๊ณผ ๋ฐ์ดํฐ ์ ์ฅ ๋ก์ง์ ๋ช
ํํ๊ฒ ๊ตฌ๋ถํ ์ ์์ด์ ์ ์ง๋ณด์์ฑ๊ณผ ํ์ฅ์ฑ์ด ํฅ์ํ๋ค๋ ์ฅ์ ์ด ์๋ค.
์ด๋ฅผ ์ฒ์์ ์ ์ฉํด ๋ณด์์ง๋ง, ์ฌ์ค ์ด๋ฅผ ๋ถ๋ฆฌํด์ ์ป๋ ์ด์ ๋ณด๋ค ์ฝ๋์ ๋ณต์ก์ฑ๋ง ๋์ด๋์ ์ป๋ ๋จ์ ์ด ํฌ๋ค๊ณ ์๊ฐํ๋ค.
์๋ฅผ ๋ค์ด Update ๊ด๋ จ ๊ธฐ๋ฅ์ ๊ตฌํํ ๋, ๋๋ฉ์ธ๊ณผ ์ํฐํฐ๋ฅผ ๋ถ๋ฆฌํ์ง ์๋๋ค๋ฉด "๋ํฐ ์ฒดํน"์ ํตํด ๊ตณ์ด Save๋ฅผ ๋ค์ ํ ํ์๊ฐ ์์๋ค. ํ์ง๋ง ๋๋ฉ์ธ๊ณผ ์ํฐํฐ๋ฅผ ๋ถ๋ฆฌํ๋ค๋ฉด, ํด๋น ์ํฐํฐ๋ฅผ JPA๋ฅผ ํตํด ์ฐพ๊ณ , ์ฐพ์ ์ํฐํฐ๋ฅผ ๋๋ฉ์ธ์ผ๋ก ๋ณ๊ฒฝ, ๋๋ฉ์ธ์ ์์ , ๋๋ฉ์ธ์ ์ํฐํฐ๋ก ๋ณ๊ฒฝ, ์ํฐํฐ๋ฅผ JPA๋ฅผ ํตํด ๋ค์ ์ ์ฅํ๋ ๊ณผ์ ์ ๊ฑฐ์ณ์ผ ํ๋ค.
๊ทธ๋์ "๋๋ฉ์ธ๊ณผ ์ํฐํฐ" ๋ถ๋ฆฌ๋ ์ ์ฉํ์ง ์๊ณ ์ด ๊ธ์ "๐ฅTroubleShooting๐ฅ"์ ํด๊ฒฐํ๋ค.