This commit is contained in:
dean
2026-03-20 13:31:16 +09:00
parent efbdbfd632
commit 17ca27087a
7 changed files with 167 additions and 26 deletions

98
shp-exporter/DOCKER.md Normal file
View File

@@ -0,0 +1,98 @@
# Docker 빌드 및 실행 가이드
## 추가된 파일
| 파일 | 설명 |
|------|------|
| `Dockerfile` | 멀티스테이지 빌드 정의 |
| `.dockerignore` | Docker 빌드 컨텍스트 제외 목록 |
---
## Dockerfile 구조
### Stage 1 — Builder (`eclipse-temurin:21-jdk-jammy`)
1. Gradle wrapper 및 `build.gradle` 복사 → 의존성 레이어 캐싱
2. 소스 코드 복사 후 `./gradlew clean bootJar -x test` 실행
3. 출력: `build/libs/shp-exporter-v2.jar`
### Stage 2 — Runtime (`eclipse-temurin:21-jre-jammy`)
- JDK 없이 JRE만 포함 → 이미지 크기 최소화
- 출력 디렉토리 `/data/model_output/export` 사전 생성
- JVM 옵션 포함 (`-Xmx4g`, G1GC 튜닝 등)
---
## 빌드
```bash
docker build -t shp-exporter .
```
---
## 실행
### Spring Batch 모드 (권장)
```bash
docker run --rm \
-v /data/model_output/export:/data/model_output/export \
-e GEOSERVER_USERNAME=admin \
-e GEOSERVER_PASSWORD=geoserver \
shp-exporter \
--batch \
--converter.batch-ids[0]=252
```
### GeoServer 등록 포함
```bash
docker run --rm \
-v /data/model_output/export:/data/model_output/export \
-e GEOSERVER_USERNAME=admin \
-e GEOSERVER_PASSWORD=geoserver \
shp-exporter \
--batch \
--geoserver.enabled=true \
--converter.inference-id=D5E46F60FC40B1A8BE0CD1F3547AA6 \
--converter.batch-ids[0]=252 \
--converter.batch-ids[1]=253
```
### Shapefile 업로드 모드
```bash
docker run --rm \
-v /data/model_output/export:/data/model_output/export \
-e GEOSERVER_USERNAME=admin \
-e GEOSERVER_PASSWORD=geoserver \
shp-exporter \
--upload-shp /data/model_output/export/path/to/file.shp \
--layer layer_name
```
### DB 주소 오버라이드
`application-prod.yml`의 DB 호스트(`kamco-cd-postgis`)가 네트워크 환경과 다를 경우:
```bash
docker run --rm \
--network your-network \
-v /data/model_output/export:/data/model_output/export \
shp-exporter \
--batch \
--spring.datasource.url=jdbc:postgresql://HOST:5432/kamco_cds \
--converter.batch-ids[0]=252
```
---
## 주의사항
- **볼륨 마운트 필수**: 출력 파일(`/data/model_output/export`)은 호스트 볼륨으로 마운트하지 않으면 컨테이너 종료 시 소실됨
- **네트워크**: DB 호스트명 `kamco-cd-postgis`가 컨테이너에서 resolve되어야 함 (`--network` 또는 `--add-host` 활용)
- **GeoServer 크리덴셜**: `GEOSERVER_USERNAME` / `GEOSERVER_PASSWORD` 환경변수로 주입 (`application-prod.yml`에 하드코딩된 값은 덮어씌워짐)
- **`.dockerignore``.gitignore`에 등록**되어 있어 git에 커밋되지 않음 — 필요 시 `.gitignore`에서 해당 라인 제거

38
shp-exporter/Dockerfile Normal file
View File

@@ -0,0 +1,38 @@
# ---- Build Stage ----
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /workspace
# Gradle wrapper 및 빌드 설정 복사 (캐시 레이어 최적화)
COPY gradlew settings.gradle build.gradle ./
COPY gradle ./gradle
# 의존성 다운로드 (소스 변경 시 재빌드 방지)
RUN chmod +x gradlew && ./gradlew dependencies --no-daemon -q || true
# 소스 복사 후 빌드 (테스트 제외)
COPY src ./src
RUN ./gradlew clean bootJar -x test --no-daemon -q
# ---- Runtime Stage ----
FROM eclipse-temurin:21-jre-jammy
WORKDIR /app
# 출력 디렉토리 생성
RUN mkdir -p /data/model_output/export
# JAR 복사
COPY --from=builder /workspace/build/libs/shp-exporter-v2.jar app.jar
# GeoServer 크리덴셜은 환경변수로 주입
ENV GEOSERVER_USERNAME=""
ENV GEOSERVER_PASSWORD=""
ENTRYPOINT ["java", \
"-Xmx4g", "-Xms512m", \
"-XX:+UseG1GC", \
"-XX:MaxGCPauseMillis=200", \
"-XX:G1HeapRegionSize=16m", \
"-XX:+ParallelRefProcEnabled", \
"-jar", "app.jar"]

View File

@@ -14,27 +14,16 @@ java {
}
}
//repositories {
// mavenCentral()
// maven {
// url 'https://repo.osgeo.org/repository/release/'
// }
// maven {
// url 'https://repo.osgeo.org/repository/geotools-releases/'
// }
// maven {
// url 'https://repo.osgeo.org/repository/snapshot/'
// }
//}
def repoUrl = System.getProperty("org.gradle.project.repoUrl")
?: System.getenv("ORG_GRADLE_PROJECT_repoUrl")
?: "http://172.16.4.56:18100/repository/maven-public/"
repositories {
mavenCentral()
maven {
url = uri(repoUrl)
allowInsecureProtocol = true
url 'https://repo.osgeo.org/repository/release/'
}
maven {
url 'https://repo.osgeo.org/repository/geotools-releases/'
}
maven {
url 'https://repo.osgeo.org/repository/snapshot/'
}
}
@@ -98,3 +87,10 @@ spotless {
tasks.named('test') {
useJUnitPlatform()
}
bootRun {
jvmArgs = ['-Xmx4g', '-Xms512m', '-XX:+UseG1GC',
'-XX:MaxGCPauseMillis=200', // GC 목표 멈춤 시간
'-XX:G1HeapRegionSize=16m', // 큰 geometry 객체 처리
'-XX:+ParallelRefProcEnabled'] // 참조 처리 병렬화
}

View File

@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
#distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionUrl=http\://172.16.4.56:18100/repository/gradle-distributions/gradle-8.14.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
#distributionUrl=http\://172.16.4.56:18100/repository/gradle-distributions/gradle-8.14.3-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@@ -29,9 +29,9 @@ converter:
crs: 'EPSG:5186'
batch:
chunk-size: 5000 # 청크 크기 증가 (1000 → 5000, 성능 5배 향상)
chunk-size: 1000 # 청크 크기 증가 (1000 → 5000, 성능 5배 향상)
skip-limit: 100 # 청크당 skip 허용 건수
fetch-size: 5000 # JDBC 커서 fetch 크기 (chunk-size와 동일하게)
fetch-size: 1000 # JDBC 커서 fetch 크기 (chunk-size와 동일하게)
enable-partitioning: false
geoserver:

View File

@@ -29,9 +29,9 @@ converter:
crs: 'EPSG:5186'
batch:
chunk-size: 5000 # 청크 크기 (1000→5000, 성능 5배 향상, 메모리 ~200MB per chunk)
chunk-size: 1000 # 4.7M 건 OOM 방지: 청크별 트랜잭션 커밋으로 GeoTools 메모리 해제
skip-limit: 100 # 청크당 skip 허용 건수
fetch-size: 5000 # JDBC 커서 fetch 크기 (chunk-size와 동일하게)
fetch-size: 1000 # JDBC 커서 fetch 크기 (chunk-size와 동일하게)
enable-partitioning: false # 초기에는 비활성화
partition-concurrency: 4 # Map ID별 병렬 처리 동시성 (4=~300MB, 8=~600MB)
@@ -46,7 +46,7 @@ geoserver:
logging:
level:
com.kamco.makesample: DEBUG
com.kamco.makesample: INFO # DEBUG → INFO: 4.7M 건 write 중 불필요한 로그 I/O 제거
org.springframework: WARN
pattern:
console: '%d{yyyy-MM-dd HH:mm:ss} - %msg%n'

View File

@@ -0,0 +1,9 @@
java -Xmx4g -Xms512m -XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 -XX:G1HeapRegionSize=16m \
-jar build/libs/shp-exporter.jar \
--batch \
--converter.inference-id=test009 \
--converter.batch-ids[0]=111 \
--converter.batch-ids[1]=114 \
--converter.batch-ids[2]=162 \
--geoserver.enabled=true