fix: 배치 Job 0건 처리 버그 수정 (메모리 최적화가 배치 데이터 삭제)
PerformanceOptimizationManager.performMemoryOptimization()에서 vesselDataHolder.clear()를 제거하여 배치 실행 중 로드된 데이터 보호. DailyTrackCache 4.3GB 상주로 메모리 83% → 70% 임계값에서 매번 트리거되어 방금 로드한 24K건 배치 데이터가 GC로 소실되던 문제 해결. 변경사항: - performMemoryOptimization(): vesselDataHolder/vesselTrackDataHolder.clear() 제거 - beforeJob 메모리 임계값: 70% → 90% - afterChunk 긴급 최적화 임계값: 85% → 95% - 캐시 메모리 한도: 5GB → 6GB (일 평균 ~720MB × 7일 = ~5GB) - .gitignore에 *.log 추가, 로그 파일 트래킹 제거 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
부모
51f588476f
커밋
121a7b7d01
1
.gitignore
vendored
1
.gitignore
vendored
@ -36,6 +36,7 @@ scripts/
|
|||||||
.claude
|
.claude
|
||||||
.mvn/
|
.mvn/
|
||||||
logs/
|
logs/
|
||||||
|
*.log
|
||||||
sql/
|
sql/
|
||||||
*.md
|
*.md
|
||||||
nul
|
nul
|
||||||
@ -41,9 +41,10 @@ public class PerformanceOptimizationListener implements JobExecutionListener, St
|
|||||||
String jobName = jobExecution.getJobInstance().getJobName();
|
String jobName = jobExecution.getJobInstance().getJobName();
|
||||||
log.info("Starting performance optimization for job: {}", jobName);
|
log.info("Starting performance optimization for job: {}", jobName);
|
||||||
|
|
||||||
// 메모리 상태 확인 및 최적화
|
// 메모리 상태 확인 및 최적화 (90% 이상에서만 트리거)
|
||||||
if (optimizationManager.getStatus().getMemoryUsage().getPercentage() > 70) {
|
// DailyTrackCache가 4~5GB 상주하므로 70%에서는 매번 트리거되어 불필요한 GC 유발
|
||||||
log.warn("High memory usage detected before job start, performing optimization");
|
if (optimizationManager.getStatus().getMemoryUsage().getPercentage() > 90) {
|
||||||
|
log.warn("High memory usage detected before job start (>90%), performing optimization");
|
||||||
optimizationManager.performMemoryOptimization();
|
optimizationManager.performMemoryOptimization();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +139,8 @@ public class PerformanceOptimizationListener implements JobExecutionListener, St
|
|||||||
if (duration > 10000) { // 10초 이상
|
if (duration > 10000) { // 10초 이상
|
||||||
log.warn("Chunk processing in step {} took {} ms", stepName, duration);
|
log.warn("Chunk processing in step {} took {} ms", stepName, duration);
|
||||||
|
|
||||||
// 메모리 압박 확인
|
// 메모리 압박 확인 (95% 이상에서만 긴급 최적화)
|
||||||
if (optimizationManager.getStatus().getMemoryUsage().getPercentage() > 85) {
|
if (optimizationManager.getStatus().getMemoryUsage().getPercentage() > 95) {
|
||||||
log.error("Critical memory usage during chunk processing, triggering optimization");
|
log.error("Critical memory usage during chunk processing, triggering optimization");
|
||||||
optimizationManager.performMemoryOptimization();
|
optimizationManager.performMemoryOptimization();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -146,14 +146,14 @@ public class PerformanceOptimizationManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 메모리 최적화 수행
|
* 메모리 최적화 수행
|
||||||
|
*
|
||||||
|
* 주의: vesselDataHolder/vesselTrackDataHolder는 배치 Job 실행 중
|
||||||
|
* SharedDataJobListener가 로드한 데이터를 보유하므로 clear하면 안 됨.
|
||||||
|
* Job 종료 후 SharedDataJobListener.afterJob()에서 자체 정리함.
|
||||||
*/
|
*/
|
||||||
public void performMemoryOptimization() {
|
public void performMemoryOptimization() {
|
||||||
long beforeMemory = getMemoryUsage().getUsed();
|
long beforeMemory = getMemoryUsage().getUsed();
|
||||||
|
|
||||||
// 데이터 홀더 정리
|
|
||||||
vesselDataHolder.clear();
|
|
||||||
vesselTrackDataHolder.clear();
|
|
||||||
|
|
||||||
// 캐시 정리 (필요시)
|
// 캐시 정리 (필요시)
|
||||||
if (getMemoryUsage().getPercentage() > 80) {
|
if (getMemoryUsage().getPercentage() > 80) {
|
||||||
areaCache.clearCache();
|
areaCache.clearCache();
|
||||||
|
|||||||
@ -110,7 +110,7 @@ vessel: # spring 하위가 아닌 최상위 레벨
|
|||||||
jdbc-url: jdbc:postgresql://10.188.141.230:5432/mdadb2?currentSchema=gis&options=-csearch_path=gis,public&TimeZone=Asia/Seoul
|
jdbc-url: jdbc:postgresql://10.188.141.230:5432/mdadb2?currentSchema=gis&options=-csearch_path=gis,public&TimeZone=Asia/Seoul
|
||||||
username: mda
|
username: mda
|
||||||
password: mda#8932
|
password: mda#8932
|
||||||
table-name: t_ship_integration_sub # gis 스키마는 jdbc-url의 currentSchema로 지정
|
table-name: gis.t_ship_integration_sub # gis 스키마는 jdbc-url의 currentSchema로 지정
|
||||||
batch:
|
batch:
|
||||||
# Area Statistics 처리를 위한 별도 설정
|
# Area Statistics 처리를 위한 별도 설정
|
||||||
area-statistics:
|
area-statistics:
|
||||||
@ -272,7 +272,7 @@ cache:
|
|||||||
daily-track:
|
daily-track:
|
||||||
enabled: true
|
enabled: true
|
||||||
retention-days: 7 # D-1 ~ D-7 (오늘 제외)
|
retention-days: 7 # D-1 ~ D-7 (오늘 제외)
|
||||||
max-memory-gb: 5 # 최대 5GB
|
max-memory-gb: 6 # 최대 6GB (일 평균 ~720MB × 7일 = ~5GB)
|
||||||
warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음)
|
warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음)
|
||||||
|
|
||||||
# WebSocket 부하 제어 설정
|
# WebSocket 부하 제어 설정
|
||||||
|
|||||||
1840982
vessel-batch.2026-02-07.1.log
1840982
vessel-batch.2026-02-07.1.log
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
Load Diff
1796304
vessel-batch.2026-02-07.2.log
1796304
vessel-batch.2026-02-07.2.log
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
Load Diff
1054780
vessel-batch.2026-02-07.log
1054780
vessel-batch.2026-02-07.log
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
Load Diff
146242
vessel-batch.log
146242
vessel-batch.log
파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
Load Diff
불러오는 중...
Reference in New Issue
Block a user