설계가 마무리되고 드디어 구현 단계에 들어갔다. 멀티레포 방식으로 진행하는 만큼 각 서비스별로 레포를 만들고 초기 세팅을 해야 했다. 이번 편에서는 기술 스택 선택 이유부터 GitHub 세팅까지 정리해보려 한다.
1. 기술 스택
Java 21
Java 21을 선택한 가장 큰 이유는 가상 스레드(Virtual Thread) 지원이다.
가상 스레드는 JVM 위에서 생성 및 실행되는 경량 스레드로 플랫폼 스레드보다 훨씬 가볍고 더 적은 리소스를 사용한다. 티켓팅 서비스 특성상 오픈 순간 대량의 동시 요청이 몰리는데, 가상 스레드를 활용하면 더 적은 리소스로 더 많은 요청을 처리할 수 있다.
Spring Boot 3.5.13
Java 21 가상 스레드를 지원하는 최신 버전이다.
Spring Cloud 2025.0.1
Config Server, Eureka, OpenFeign 등 MSA 구성에 필요한 컴포넌트들을 제공한다.
PostgreSQL
추후 PGVector 사용 가능성을 고려해서 선택했다.
Flyway
DB 마이그레이션 도구로 스키마 변경 이력을 코드로 관리할 수 있다.
Rest Docs
테스트 코드 기반으로 문서를 생성해서 실제 동작하는 코드와 문서 간의 일관성을 100% 보장하고, 운영 코드에 문서화 어노테이션이 남지 않아 코드 순수성을 유지할 수 있다.
2. 멀티레포 방식
이번 프로젝트는 멀티레포 방식으로 진행한다. 각 서비스가 독립적인 레포를 가지는 구조다.
first-ticket/
├── common-module ← 공통 모듈 (별도 레포)
├── config-server ← 설정 서버 (별도 레포)
├── eureka-server ← 서비스 디스커버리 (별도 레포)
├── gateway-server ← API Gateway (별도 레포)
├── user-service ← 사용자 도메인 (별도 레포)
├── payment-service ← 결제 도메인 (별도 레포)
├── booking-service ← 예매 도메인 (별도 레포)
├── program-service ← 프로그램 도메인 (별도 레포)
└── queue-service ← 대기열 도메인 (별도 레포)
모노레포 방식과 달리 각 레포가 독립적인 프로젝트라 실행에 필요한 파일이 모두 있어야 한다.
3. build.gradle 의존성 구성
plugins {
id 'java'
id 'org.springframework.boot' version '3.5.13'
id 'io.spring.dependency-management' version '1.1.7'
}
group = 'com.first-ticket'
version = '0.0.1-SNAPSHOT'
description = 'payment-service'
java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}
repositories {
mavenCentral()
}
ext {
set('springCloudVersion', '2025.0.1')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
dependencies {
// Web
implementation 'org.springframework.boot:spring-boot-starter-web'
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// PostgreSQL
runtimeOnly 'org.postgresql:postgresql'
// Flyway
implementation 'org.flywaydb:flyway-core'
implementation 'org.flywaydb:flyway-database-postgresql'
// Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
// Kafka
implementation 'org.springframework.kafka:spring-kafka'
// Spring Cloud Config Client
implementation 'org.springframework.cloud:spring-cloud-starter-config'
// Eureka Client
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Test
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.kafka:spring-kafka-test'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}
tasks.named('test') {
useJUnitPlatform()
}
dependencyManagement 블록이 필요한 이유
Spring Cloud는 여러 라이브러리들이 BOM(Bill of Materials) 방식으로 묶음 관리된다. BOM을 import하면 각 라이브러리 버전을 직접 명시하지 않아도 Spring Cloud 버전에 맞는 버전이 자동으로 맞춰진다. 없으면 버전 충돌이 날 수 있다.
4. .editorconfig 설정
운영체제 간 줄바꿈 규칙 통일과 코드 스타일 충돌 방지를 위해 추가한다.
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
[*.java]
max_line_length = 120
5. .gitattributes 설정
Windows는 줄바꿈이 CRLF, Mac/Linux는 LF라서 Git에서 파일이 변경된 것처럼 보이는 문제를 방지한다.
# 텍스트 파일 기본: LF 정규화
* text=auto eol=lf
# gradlew는 반드시 LF (Unix 실행 파일)
gradlew text eol=lf
# Windows 배치 파일
*.bat text eol=crlf
*.cmd text eol=crlf
# 바이너리 (변환 금지)
*.jar binary
*.class binary
*.png binary
*.jpg binary
*.gif binary
6. GitHub 레포 세팅
브랜치 전략
main ← 배포 브랜치 (Protected)
dev ← 개발 통합 브랜치 (Protected)
feat/* ← 기능 개발 브랜치
브랜치 보호 규칙 (main, dev)
- 직접 push 금지
- PR 필수
- CI 통과 필수
- 승인 1명 이상 필수
- 삭제 금지
브랜치 네이밍 규칙
feat/{이슈번호}-{간단한-기능명}
예시)
feat/1-domain-setup
feat/5-payment-create
feat/7-payment-confirm
커밋 메시지 규칙
<type>: <subject>
<body>
<footer>
| feat | 새 기능 |
| fix | 버그 수정 |
| refactor | 리팩토링 |
| docs | 문서 변경 |
| style | 코드 스타일 |
| test | 테스트 코드 |
| chore | 빌드, 설정 |
예시
feat: 결제 생성 API 구현
- POST /internal/v1/payments 엔드포인트 구현
- orderId UUID 기반 생성
- 결제 레코드 PENDING 상태로 초기화
Closes #5
이슈 제목 형식
[feat][payment] 도메인 엔티티 구현
[fix][payment] 중복 결제 방지 로직 수정
PR 흐름
feat/* → dev (PR)
dev → main (배포 시점에 PR)
설계만 할 때는 몰랐는데 실제로 레포 만들고 세팅하다 보니 팀원들이랑 맞춰야 할 것들이 생각보다 많았다. 브랜치 전략, 커밋 메시지 규칙, .editorconfig까지 전부 통일해두지 않으면 나중에 코드 리뷰할 때 스타일 충돌로 시간 낭비가 생긴다.
다음 편에서는 패키지 구조 설계와 개발 계획을 정리할 예정이다.
'Spring 개발일지' 카테고리의 다른 글
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 결제 도메인 엔티티 구현 (0) | 2026.04.29 |
|---|---|
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 프로젝트 구조 설계 & 개발 계획 (0) | 2026.04.28 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 프로젝트 목표 정리 & 미니 발표 준비 (0) | 2026.04.25 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 도메인 모델 & 인프라 설계 (0) | 2026.04.24 |
| [팀프로젝트] MSA 기반 티켓팅 프로그램 - 레이스 컨디션 발견 및 설계 재검토 (2) | 2026.04.23 |