반응형
개요
지난 시즌 개발 중 신규 프로젝트 시작할 때 큰 귀찮음이 있었다.
1. 프로젝트마다 중복되는 코드: log 설정, db설정, kafka 설정, 등등..
2. 프로젝트마다 중복되는 작업: github, jenkins CI/CD, docker config 등등..
이런 귀찮음은 결국 신규 프로젝트를 시작할 때 부담으로 작용하게 되었고
간단한 아이디어를 테스트 하기에 좋지 못했다.
이번 시즌에는 이러한 부분을 사전에 방지하고자 한다.
이 글은 Gradle의 Multi-Project 구조를 통해
이러한 문제상황을 해결해보려 한다.
Multi-Project 구조 설계
Gradle은 Multi-Project 구조를 지원한다.
이번 프로젝트는 2-depth 이상으로 구성하려 한다.
Root project 'pbear-root'
\--- Project ':pbear-spring'
+--- Project ':pbear-spring:pbear-lib'
\--- Project ':pbear-spring:pbear-sample'
Project 구조이다.
전체적으로 java 프로젝트를 대상으로 하며
일단 Spring Project를 1-depth로 잡았다.
2-depth부터 개발이 진행될 프로젝트들이 나열되는데
기본적으로 lib를 두고, spring-project에서 사용될 공통 코드 및 설정을 implementation 해서 사용하고자 한다.
[root] setting.gradle
rootProject.name = 'pbear-root'
include 'pbear-spring'
include 'pbear-spring:pbear-lib'
include 'pbear-spring:pbear-sample'
특이사항은 없으며
하위 프로젝트의 build.gradle을 include 시켰다.
[root] build.gradle
group = 'com.pbear'
subprojects {
apply plugin: 'java'
apply plugin: 'java-library'
sourceCompatibility = 17
targetCompatibility = 17
dependencies {
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
}
repositories {
mavenCentral()
}
}
subprojects를 통해 하위 프로젝트에 적용될 plugin, dependencies 및 repositories를 설정했다.
[pbear-spring] build.gradle
plugins {
id 'org.springframework.boot' version '3.2.0' apply false
id 'io.spring.dependency-management' version '1.1.4' apply false
}
ext {
set('springCloudVersion', "2023.0.0")
}
subprojects {
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
test {
useJUnitPlatform()
}
}
1-depth의 spring을 주제로 묶은 프로젝트이다.
여기서 spring의 dependencies를 통합해서 관리하고자 한다.
기본적으로 spring의 dependency-management 플러그인을 사용하고, spring boot 및 spring cloud version을 관리할 수 있도록 세팅했다.
[pbear-lib] build.gradle
version = '0.0.1'
dependencies {
implementation 'org.springframework.boot:spring-boot-autoconfigure'
}
2-depth의 Library에 해당하는 프로젝트이다.
추후 추가될 예정이며, 여기부터는 project version 관리를 한다.
[pbear-sample] build.gradle
version = '0.0.0'
dependencies {
implementation project(':pbear-spring:pbear-lib')
implementation 'org.springframework.boot:spring-boot-starter-webflux'
}
REST echo기능을 하나 넣은 sample project이다.
추후 추가되는 프로젝트는 위처럼 pbear-lib를 implementation을 해서 사용한다.
위 프로젝트 구조를 통해
프로젝트 추가 시 낭비되는 작업들을 최소화시킬 수 있을 것이라 판단된다.
ex) github project 추가, spring dependency 작업, 중복 기능 구현, 설정 등
Common logback 설정
[pbear-lib] logback.xml
Root project 'pbear-root'
\--- Project ':pbear-spring'
+--- Project ':pbear-spring:pbear-lib'
\--- src/main/resources/logback.xml
\--- Project ':pbear-spring:pbear-sample'
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty name="APP_NAME" source="spring.application.name"/>
<springProfile name="local">
<property name="FILE_PATH" value="/users/xxxxx/workspace/logs"/>
<property name="FILE_NAME" value="${APP_NAME}"/>
</springProfile>
<springProfile name="release">
<property name="FILE_PATH" value="/logs"/>
<property name="FILE_NAME" value="${APP_NAME}"/>
</springProfile>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyyMMdd HH:mm:ss} [%thread] %-5level%logger{5} - %msg %n</pattern>
</encoder>
</appender>
<appender name="RollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${FILE_PATH}/${FILE_NAME}.log</file>
<encoder>
<pattern>%d{yyyyMMdd HH:mm:ss} [%thread] %-5level%logger{5} - %msg %n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${FILE_PATH}/${FILE_NAME}.log.%d{yyyy-MM-dd}_%i.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>1GB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<springProfile name="local">
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</springProfile>
<springProfile name="release">
<root level="INFO">
<appender-ref ref="RollingFileAppender" />
</root>
</springProfile>
</configuration>
공통 library에 자주 사용하는 logback을 넣고 다른 project에서 implementation 하면
실제 기동 시 해당 logback이 적용된다.
변수는 모두 spring properties로 받아온다.
이로서 신규 프로젝트는 로깅에 대한 설정을 스킵할 수 있다.
또한 log관련 변동사항이 다 같이 적용되고, log의 형식도 통일할 수 있다.
Next..
신규 프로젝트마다. CI / CD설정하고, docker 설정 만드는 것도 많이 귀찮은 작업이었다.
프로젝트 구조를 잡았으니
다음은 Jenkins를 통해 CI / CD를 공통화할 계획이다.
REFERENCE
https://docs.gradle.org/current/userguide/multi_project_builds.html
반응형
'[시즌2] 개인서버 개발 > 시즌2 설계(완)' 카테고리의 다른 글
API Gateway with Passport (0) | 2024.03.09 |
---|---|
Spring Properties from Lib Resources (PropertySourcesPlaceholderConfigurer, EnvironmentPostProcessor) (1) | 2024.01.02 |
AnnotationProcessor를 통한 project 내 ServerInfo Enum 생성 (1) | 2023.12.25 |
Gradle Docker build (feat. Jenkins CI/CD) (1) | 2023.12.22 |