07 Build
07 Build
1. Note
1. 빌드도구 - 빌드
- Spring Boot는 메이븐 또는 그레들 같은 빌드 도구를 사용해서 소스 코드를 컴파일하는데
- 메이븐의 경우는 pom.xml, 그레들의경우에는 build.gradle를 통해서 빌드에 관한 기본 설정을 확인하고
- 필요한 라이브러리들을 pom.xml 또는 build.gradle에 정의된 저장소 설정을 기준으로,
- 메이븐 센트럴이나 넥서스 같은 라이브러리 저장소에서 받아
- 함께 묶어 최종 산출물로 jar 또는 war 파일을 만듬.
- 메이븐이나 그레들은 어떤 형태의 결과물을 만들 것인지를 정의하고 그 결과물을 생성하는 역할만 담당
- 빌드가 완료되면 만들어진 jar 또는 war 파일은 각각의 실행 방식에 맞는 실행 환경에서 동작
- jar 파일의 경우에는 JVM이 직접 실행하고, 내장 WAS(Tomcat 등)가 함께 포함되어, java -jar 명령만으로 애플리케이션을 바로 실행
- war 파일은 Tomcat, JBoss, WebLogic 같은 외부 WAS에 배포되어, WAS에 의해 로딩되고 실행·관리되는 배포 단위
2. Build
1. Build
- 사람이 작성한 소스 코드와 리소스를 실행 가능한 산출물로 변환하는 일련의 자동화된 과정
- 소스 코드와 설정을 기준으로 동일한 결과물을 언제 어디서든 재현 가능하게 만들어주는 자동화 과정
*.jar,*.war형태로 만들어짐
2. Build 흐름
- 소스 코드 컴파일 :
.java → .class - 리소스 처리 :
application.yml,static 파일,템플릿 파일 등 복사 - 의존성 해결 :
pom.xml / build.gradle에 정의된 라이브러리 다운로드, 클래스패스 구성 - 테스트 실행 : JUnit 등 단위 테스트 수행
- 패키징:
.class + 라이브러리 + 리소스 → jar 또는 war 생성 - 설치 또는 배포 : 로컬 저장소 또는 원격 저장소에 결과물 등록
3. CI/CD
1. CI/CD
- CI(Continuous Integration): 코드가 커밋될 때마다 자동 빌드 + 테스트 수행
- CD(Continuous Delivery/Deployment): 빌드된 산출물을 자동으로 환경(테스트/운영)에 배포
2. CI/CD - BUILD
| 단계 | 역할 | 사용 도구 / 예시 | 비고 |
|---|---|---|---|
| 1. 코드 커밋 | 개발자가 소스 코드를 버전 관리 시스템에 커밋 | Git, SVN | CI 트리거 시작점 |
| 2. 코드 통합 & 빌드 | 커밋된 코드를 통합하고, 빌드 수행(jar/war 생성) | Maven, Gradle | CI 단계 핵심, 테스트 포함 |
| 3. 자동 테스트 | 단위 테스트, 통합 테스트 수행 | JUnit, Mockito, TestNG | 빌드와 동시에 수행되는 경우 많음 |
| 4. 아티팩트 저장 | 빌드 산출물(jar/war) 중앙 저장소에 업로드 | Nexus, Artifactory | 배포 전 준비 단계 |
| 5. 배포 | 테스트/스테이징/운영 환경에 자동 배포 | Jenkins, GitLab CI, Ansible, Kubernetes | CD 단계 |
| 6. 모니터링 & 피드백 | 배포 후 성능, 로그, 오류 모니터링 | Prometheus, ELK, Grafana | 운영 피드백 |
3. Jenkins / GitHub Action
- CI/CD 파이프라인을 실행하는 자동화 도구
- 빌드, 테스트, 이미지 생성, 배포 명령을 “대신 실행”해주는 주체
- 비교
| 구분 | Jenkins | GitHub Actions |
|---|---|---|
| 성격 | 독립적인 CI/CD 서버 | GitHub에 내장된 CI/CD |
| 운영 주체 | 직접 설치·운영 | GitHub 관리형 |
| 초기 셋업 | 무겁고 복잡 | 매우 간단 |
| 파이프라인 정의 | Jenkinsfile (Groovy) | YAML |
| 러닝 환경 | 고정 에이전트 또는 노드 | 매 실행마다 새 러너 |
| 쿠버네티스 연동 | kubectl / helm 직접 구성 | kubectl / helm 바로 사용 |
| 확장 방식 | 플러그인 중심 | Action 재사용 |
| 유지보수 비용 | 높음 | 낮음 |
| 대규모 파이프라인 | 강점 | 관리 난이도 증가 |
| GitHub 연동 | 별도 설정 필요 | 기본 통합 |
| 비용 구조 | 서버 비용 + 운영 비용 | 일정 사용량까지 무료 |
※ Helm은 쿠버네티스용 패키지 매니저
※ Jenkins 파이프라인은 Groovy
3. war / jar
1. war / jar
- 자바 아카이브 형식, zip 기반
- 클래스(.class), 리소스, 메타데이터를 묶은 결과물
- 스스로 실행하는지(jar), WAS에 실행하는지 차이(war)
2. war / jar 비교
| 구분 | jar | war |
|---|---|---|
| 기본 개념 | 실행 가능한 애플리케이션 패키지 | WAS에 배포되는 애플리케이션 패키지 |
| 실행 주체 | JVM이 직접 실행 | 외부 WAS가 실행 |
| 실행 방식 | java -jar app.jar | Tomcat, JBoss 등에 배포 |
| 서버 포함 여부 | 스프링부트 기준 내장 WAS 포함 | WAS 미포함 |
| 스프링부트 기본값 | O | X |
| main 메서드 | 필요 | 필요 없음 (WAS가 로딩) |
| 배포 단위 | 서비스 단위 | WAS 단위 |
| 구조 예시 | BOOT-INF/classes BOOT-INF/lib | WEB-INF/classes WEB-INF/lib |
| 의존성 관리 | 애플리케이션이 전부 포함 | 일부는 WAS에 의존 |
| 컨테이너 환경 | 매우 적합 | 상대적으로 불리 |
| MSA 환경 | 표준에 가까움 | 거의 사용 안 함 |
| 레거시 환경 | 드묾 | 매우 흔함 |
| 스케일링 | 서비스별 독립 스케일 | WAS 전체 스케일 |
| 책임 모델 | 앱이 실행 환경까지 책임 | 실행 환경은 WAS 책임 |
3. war 구조
1. was - war 배포
- WAR 빌드 단계
- Spring Boot 프로젝트를 WAR로 빌드
- 의존성 라이브러리와 애플리케이션 클래스가 WAR 파일로 묶임
- WAR 안에는 WEB-INF/classes, WEB-INF/lib 등 표준 디렉터리 구조 포함
- WAS 준비 단계
- WAS(JBoss, Tomcat, WebLogic 등) 설치 및 실행 준비
- 필요하면 JDBC 드라이버를 WAS 모듈에 등록
- DB 커넥션 풀(DataSource) 설정
- standalone.xml, server.xml, 관리 콘솔 또는 CLI 사용
- JNDI 이름을 지정하여 애플리케이션에서 참조 가능
- WAR 배포 단계
- WAR 파일을 WAS의 배포 디렉터리(Tomcat: webapps, JBoss: standalone/deployments)에 복사 또는 관리 콘솔 / CLI를 통해 배포
- WAS가 WAR를 감지하고 압축 해제 후 로딩
- 서블릿 컨테이너가 초기화되고 Spring 애플리케이션 컨텍스트 생성
- DispatcherServlet 초기화
- 빈(bean) 생성 및 의존성 주입(DI)
- JNDI를 통해 WAS가 제공하는 DataSource, 트랜잭션 관리, 스레드 풀 등 인프라 자원 연결
- 실행 단계
- WAS가 HTTP 요청을 수신
- Spring DispatcherServlet이 요청을 받아 컨트롤러로 전달
- 컨트롤러 → 서비스 → 레포지토리 순으로 비즈니스 로직 처리
- 결과 반환 후 WAS가 클라이언트에 응답 전송
- 요청 처리는 WAS가 관리하는 스레드와 리소스를 사용
2. WAS - Spring war build
- 실행 주체와 라이프사이클 위임
- WAS(JBoss, Tomcat, WebLogic 등)가 실행 주체
- Spring 애플리케이션은 WAS 안에서 실행
- 서블릿 컨테이너, 스레드 관리, 커넥션 풀 등 주요 라이프사이클은 WAS가 담당
- 애플리케이션은 비즈니스 로직만 집중
- DataSource / 커넥션 풀
- 커넥션 풀은 WAS가 생성·관리
- Spring은 JNDI를 통해 풀을 가져다 사용
- 풀 크기, 커넥션 생성/회수, 종료 같은 관리는 애플리케이션이 직접 신경 쓰지 않아도 됨
- 서블릿과 컨테이너
- Spring MVC 서블릿(DispatcherServlet)도 WAS의 서블릿 컨테이너 안에서 실행
- 서블릿의 초기화, 요청 처리, 스레드 관리 등은 WAS가 담당
- Spring은 요청 처리 로직과 컨트롤러, 서비스, 레포지토리 구현에 집중
4. maven/gradle
1. maven/gradle
- 메이븐
- XML(pom.xml) 기반
- “정해진 규칙을 따르자”는 철학
- 표준 라이프사이클을 강하게 강제
- 설정이 선언적(declarative)
- 그레들
- Groovy 또는 Kotlin DSL 기반(build.gradle)
- “필요하면 직접 정의하자”는 철학
- 라이프사이클을 유연하게 커스터마이징 가능
- 설정 + 로직을 함께 작성 가능(스크립트)
2. maven/gradle 비교
| 구분 | 메이븐 (Maven) | 그레들 (Gradle) |
|---|---|---|
| 설정 방식 | pom.xml 기반 XML 설정 | build.gradle 또는 build.gradle.kts (Groovy/Kotlin DSL) |
| 선언적 설정 중심 | 코드 기반 설정 | |
| 정해진 구조와 규칙을 따름 | 조건문, 반복문 등 로직 작성 가능 | |
| 설정은 장황하지만 일관성 높음 | 설정이 간결하지만 자유도가 높음 | |
| 커스터마이징이 제한적 | 커스터마이징이 매우 유연 | |
| 빌드 성능 | 전체 빌드 위주 | 증분 빌드 지원 |
| 변경 여부와 관계없이 재빌드되는 경우 많음 | 변경된 부분만 빌드 | |
| 빌드 캐시 개념이 약함 | 로컬/원격 빌드 캐시 적극 활용 | |
| 대규모 멀티 모듈에서 느려질 수 있음 | 멀티 모듈에서 성능 이점 큼 | |
| 의존성 관리 | Maven Central 중심 | Maven Central 등 동일 저장소 사용 |
| 트랜지티브 의존성 자동 관리 | 트랜지티브 의존성 자동 관리 | |
| 충돌 시 가까운 버전 우선 규칙 고정 | 충돌 해결 전략을 코드로 제어 가능 | |
| 의존성 관리 방식이 단순하고 예측 가능 | 버전 강제, 조건 |
5. Maven Central / Nexus
1. MavenCentral / Nexus
- 메이븐 센트럴
- 전 세계에 공개된 공식 공용 라이브러리 저장소
- 누구나 접근 가능
- 공개 오픈소스 라이브러리만 존재
- 전역 표준에 가까운 위치
- 개발자가 직접 업로드 불가(심사·절차 필요)
- Maven / Gradle / Ivy 셋다 메이븐센트럴 사용가능함.
- Nexus
- 조직이나 회사가 직접 운영하는 아티팩트 저장소 관리 서버
- 내부 네트워크 전용 가능
- 사내에서 만든 jar/war 저장 가능
- 외부 저장소를 프록시로 연결 가능
- 접근 권한, 배포 권한 제어 가능
2. 설정 위치
| 구분 | Maven | Gradle |
|---|---|---|
| 빌드 설정 파일 | pom.xml | build.gradle / build.gradle.kts |
| 기본 역할 | 프로젝트 빌드 방식, 의존성 정의 | 프로젝트 빌드 방식, 의존성 정의 |
| 기본 저장소 설정 위치 | pom.xml | build.gradle |
| 환경 단위 설정 파일 | settings.xml | init.gradle |
| 환경 설정 역할 | 저장소 강제, 인증 정보, 프록시 설정 | 저장소 강제, 공통 설정 주입 |
| 저장소 강제 가능 여부 | 가능 | 가능 |
| settings.gradle 역할 | 해당 없음 | 멀티 모듈 구조 정의 |
| 메이븐 센트럴 기본 사용 | 예 (설정 없을 때) | 예 (mavenCentral() 설정 시) |
| 넥서스 사용 방식 | settings.xml 또는 pom.xml에서 지정 | init.gradle 또는 build.gradle에서 지정 |
This post is licensed under CC BY 4.0 by the author.