signal-batch/src/main/resources/application-prod.yml
htlee 9ffaf35aeb chore: 운영 로그 레벨 정리 + daily 파티션 영구 보존
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-09 06:05:10 +09:00

338 lines
12 KiB
YAML
Raw Blame 히스토리

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

server:
port: 18090
tomcat:
threads:
max: 200
min-spare: 10
connection-timeout: 60000 # 60초로 증가
max-http-form-post-size: 50MB # 50MB로 증가
max-swallow-size: 50MB # 50MB로 증가
max-connections: 10000 # 최대 연결 수
accept-count: 100 # 대기열 크기
spring:
datasource:
# 원격 수집 DB
collect:
jdbc-url: jdbc:postgresql://211.208.115.83:5432/snpdb?currentSchema=signal&options=-csearch_path=signal,public&assumeMinServerVersion=12&reWriteBatchedInserts=true
username: snp
password: snp#8932
driver-class-name: org.postgresql.Driver
hikari:
pool-name: CollectHikariPool
connection-timeout: 30000 # 원격 연결이므로 타임아웃 증가
idle-timeout: 600000
max-lifetime: 1800000
maximum-pool-size: 80 # 20 -> 80 (총 250 중 32%, 배치 Reader 주 사용)
minimum-idle: 15 # 5 -> 15
# 원격 연결 안정성을 위한 추가 설정
connection-test-query: SELECT 1
validation-timeout: 5000
leak-detection-threshold: 60000 # 커넥션 누수 감지 (60초)
connection-init-sql: "SET TIME ZONE 'Asia/Seoul'; SET search_path TO signal, public;"
# 원격 조회 DB
query:
jdbc-url: jdbc:postgresql://211.208.115.83:5432/snpdb?currentSchema=signal&options=-csearch_path=signal,public&assumeMinServerVersion=12&reWriteBatchedInserts=true
username: snp
password: snp#8932
driver-class-name: org.postgresql.Driver
hikari:
pool-name: QueryHikariPool
connection-timeout: 5000
idle-timeout: 600000
max-lifetime: 1800000
maximum-pool-size: 180 # 120 -> 180 (WebSocket 대기열 + REST API 주 사용)
minimum-idle: 30 # 20 -> 30
connection-test-query: SELECT 1
validation-timeout: 5000
leak-detection-threshold: 60000 # 커넥션 누수 감지 (60초)
# PostGIS 함수를 위해 public 스키마를 search_path에 명시적으로 추가
connection-init-sql: "SET TIME ZONE 'Asia/Seoul'; SET search_path TO signal, public, pg_catalog; SET work_mem = '256MB'; SET synchronous_commit = 'off';"
statement-cache-size: 250
data-source-properties:
prepareThreshold: 3
preparedStatementCacheQueries: 250
# 로컬 배치 메타 DB (signal 스키마 사용)
batch:
jdbc-url: jdbc:postgresql://211.208.115.83:5432/snpdb?currentSchema=public&assumeMinServerVersion=12&reWriteBatchedInserts=true
username: snp
password: snp#8932
driver-class-name: org.postgresql.Driver
hikari:
pool-name: BatchHikariPool
maximum-pool-size: 30 # 20 -> 30 (총 250 중 12%, Spring Batch 메타데이터)
minimum-idle: 5 # 10 -> 5 (메타데이터 용도이므로 최소 유지)
connection-timeout: 30000 # 30초 타임아웃
idle-timeout: 600000
max-lifetime: 1800000
leak-detection-threshold: 60000 # 커넥션 누수 감지 (60초)
connection-init-sql: "SET TIME ZONE 'Asia/Seoul'; SET search_path TO signal, public; SET synchronous_commit = 'off';"
# Request 크기 설정
servlet:
multipart:
max-file-size: 50MB
max-request-size: 50MB
# Spring Batch 설정
batch:
job:
enabled: false
jdbc:
initialize-schema: never # always에서 never로 변경 (이미 수동으로 생성했으므로)
table-prefix: signal.BATCH_
logging:
level:
root: INFO
gc.mda.signal_batch: INFO
gc.mda.signal_batch.monitoring: INFO
org.springframework.batch: WARN
org.springframework.jdbc: WARN
org.postgresql: WARN
com.zaxxer.hikari: WARN
# 개발 환경 배치 설정 (성능 최적화)
vessel: # spring 하위가 아닌 최상위 레벨
# 통합선박 설정
integration:
enabled: true
datasource:
jdbc-url: jdbc:postgresql://211.208.115.83:5432/snpdb?currentSchema=public&assumeMinServerVersion=12&reWriteBatchedInserts=true
username: snp
password: snp#8932
ble-name: gis.t_ship_integration_sub # gis 스키마는 jdbc-url의 currentSchema로 지정
batch:
# Area Statistics 처리를 위한 별도 설정
area-statistics:
chunk-size: 1000 # 5000 → 1000
batch-size: 500 # 새로 추가
chunk-size: 10000
page-size: 5000
partition-size: 12
# 성능 최적화 설정
optimization:
enabled: true
dynamic-chunk-sizing: true
memory-optimization: true
cache-optimization: true
thread-pool-optimization: true
# 동적 청크 크기 조정
chunk:
min-size: 1000
max-size: 20000
adjustment-factor: 0.2
# 메모리 임계값
memory:
warning-threshold: 70
critical-threshold: 85
optimization-threshold: 80
# 캐시 설정
cache:
min-hit-rate: 70
area-boundary-size: 5000
# Reader 최적화
fetch-size: 200000
use-cursor-reader: true
# Bulk Insert 최적화
bulk-insert:
batch-size: 10000
parallel-threads: 8
use-binary-copy: false
# Writer 설정
writer:
use-advisory-lock: false
parallel-threads: 4
# 재시도 설정
retry:
max-attempts: 3
initial-interval: 1000
max-interval: 10000
multiplier: 2
# 스케줄러 설정
scheduler:
enabled: true
incremental:
delay-minutes: 3 # 데이터 수집 지연 고려
# Batch 메타데이터 정리 설정
metadata:
cleanup:
enabled: true # 자동 정리 활성화
retention-days: 21 # 보존 기간 (30일)
dry-run: false # false: 실제 삭제, true: 테스트만
# 궤적 비정상 검출 설정
track:
abnormal-detection:
large-gap-threshold-hours: 4 # 이 시간 이상 gap은 연결 안함
extreme-speed-threshold: 1000 # 이 속도 이상은 무조건 비정상 (knots)
enable-merger-filtering: false # VesselTrackMerger 필터링 활성화 (기본: false)
# 타임아웃 설정
query-timeout: 1800 # 30분
lock:
timeout: 30
max-retry: 5
# Health Check 설정
health:
job-timeout-hours: 2
min-partition-count: 1
# 그리드 설정
grid:
mode: haegu
haegu:
cache-enabled: true
cache-size: 2000
# 선박 최신 위치 캐시 설정 (운영 환경 활성화)
cache:
latest-position:
enabled: true # 운영 환경: 활성화
ttl-minutes: 60 # 60분 TTL
max-size: 60000 # 최대 60,000척
refresh-interval-minutes: 2 # 2분치 데이터 조회 (수집 지연 고려)
# L2 HourlyTrackCache 간소화 (운영 환경 활성화)
hourly-simplification:
enabled: true # 운영 환경: 활성화
# 비정상 궤적 검출 설정 (개선됨)
abnormal-detection:
enabled: true
5min-speed-threshold: 500 # 5분 집계 비정상 속도 임계값 (200 knots로 완화)
# 비정상 판정 기준 (명백한 비정상만 검출하도록 완화)
thresholds:
# 정박/저속 판단 기준
min-movement-nm: 0.05 # 최소 이동거리 (정박 판단)
stationary-speed-knots: 0.5 # 정박 속도 기준
# 선박 관련 임계값
vessel-physical-limit-knots: 100.0 # 선박 물리적 한계
vessel-abnormal-speed-knots: 200.0 # 선박 명백한 비정상 속도
# 항공기 관련 임계값
aircraft-physical-limit-knots: 600.0 # 항공기 물리적 한계
aircraft-abnormal-speed-knots: 800.0 # 항공기 명백한 비정상 속도
# 거리 관련 임계값
base-distance-5min-nm: 20.0 # 5분 기준 거리 (20nm로 완화)
extreme-distance-5min-nm: 100.0 # 5분간 극단적 이동거리
# Hourly/Daily 전용 임계값
hourly-daily-speed-limit: 500.0 # 시간/일 집계시 극단적 속도만 검출
# 기타 설정
distance-tolerance: 3.0 # 거리 허용 배수 (3.0으로 완화)
time-scaling-method: "sqrt" # 시간 스케일링 방법 (sqrt)
# 캐시 설정
cache:
previous-track-size: 10000 # 이전 궤적 캐시 크기
ttl-hours: 24 # 캐시 TTL
# 처리 옵션
processing:
remove-abnormal-segments: true # 비정상 구간 제거 여부
save-corrected-tracks: true # 보정된 궤적 저장 여부
exclude-stationary-vessels: false # 정박 선박 제외 여부
lenient-mode: true # 관대한 모드 활성화
# 파티션 관리 설정 (운영 환경 - application.yml 설정 오버라이드)
partition:
# 운영 환경에서는 더 긴 보관 기간 설정 가능
default-retention:
daily-partitions-retention-days: 7 # 일별 파티션 7일 보관
monthly-partitions-retention-months: 3 # 월별 파티션 3개월 보관
tables:
# 중요 데이터는 더 오래 보관
t_area_vessel_tracks:
retention-days: 60 # 구역별 선박 항적: 60일
t_grid_vessel_tracks:
retention-days: 30 # 해구별 선박 항적: 30일
t_vessel_tracks_daily:
retention-months: 0 # 일별 항적: 영구 보관
t_abnormal_tracks:
retention-months: 0 # 비정상 항적: 영구 보관
# S&P AIS API 캐시 TTL (운영: 120분)
app:
cache:
ais-target:
ttl-minutes: 120
ais-api:
username: 7cc0517d-5ed6-452e-a06f-5bbfd6ab6ade
password: 2LLzSJNqtxWVD8zC
# 일일 항적 데이터 인메모리 캐시
cache:
daily-track:
enabled: true
retention-days: 14 # D-1 ~ D-14 (2주, DP 간소화로 메모리 절감)
max-memory-gb: 10 # 최대 10GB (DP 간소화 후 일 ~400MB × 14일 ≈ 6GB + 여유)
warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음)
# 항적 데이터 메모리 예산 (64GB JVM 기준)
track:
memory-budget:
total-budget-gb: 64 # 전체 JVM 힙
cache-budget-gb: 35 # L1+L2+L3 캐시 (L3 5GB + L2 ~14GB + L1 ~3GB + 여유 13GB)
query-budget-gb: 20 # REST/WebSocket 동시 쿼리 (동시 60쿼리 × ~300MB)
max-single-query-gb: 5 # 단일 쿼리 상한
estimation-correction-factor: 1.8 # 실측 기반 보정 계수
queue-timeout-seconds: 60
warning-threshold: 0.8
critical-threshold: 0.95
# WebSocket 부하 제어 설정
websocket:
query:
max-concurrent-global: 30 # 서버 전체 동시 실행 쿼리 상한 (메모리 보호: 60→30)
max-per-session: 10 # 세션당 동시 쿼리 상한 (20→10)
queue-timeout-seconds: 60 # 글로벌 대기 큐 타임아웃 (슬롯 감소 보완: 30→60)
transport:
message-size-limit-mb: 2 # 단일 STOMP 메시지 상한 (50→2MB, 청크 1024KB 기준)
send-buffer-size-limit-mb: 50 # 세션당 송신 버퍼 상한 (사전 할당 아님, 최악 30×50MB=1.5GB)
outbound-queue-capacity: 200 # 아웃바운드 메시지 큐 (5000→200)
send-time-limit-seconds: 30 # 메시지 전송 시간 제한
memory:
heap-reject-threshold: 0.85 # 힙 사용률 85% 초과 시 새 쿼리 대기열 전환 (기본 20~24GB → 정상시 50% 미만)
session:
idle-timeout-ms: 15000 # 세션 유휴 타임아웃 15초 (60s → 15s)
server-heartbeat-ms: 5000 # 서버 하트비트 5초 (10s → 5s)
client-heartbeat-ms: 5000 # 클라이언트 하트비트 5초 (10s → 5s)
sockjs-disconnect-delay-ms: 5000 # SockJS 해제 지연 5초 (30s → 5s)
send-time-limit-seconds: 30 # 메시지 전송 시간 제한 30초 (120s → 30s)
# REST V2 부하 제어 설정
rest:
v2:
query:
timeout-seconds: 30 # 슬롯 대기 타임아웃 (초)
max-total-points: 500000 # 응답 총 포인트 상한
# 액추에이터 설정
management:
endpoints:
web:
exposure:
include: health,info,metrics,prometheus,env,loggers,threaddump,heapdump,scheduledtasks
endpoint:
health:
show-details: always
show-components: always
metrics:
tags:
application: vessel-batch-aggregation
environment: prod