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://10.188.171.182:5432/mdadb?currentSchema=signal&options=-csearch_path=signal,public&assumeMinServerVersion=12&reWriteBatchedInserts=true username: mda password: mda#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://10.188.171.182:5432/mdadb?currentSchema=signal&assumeMinServerVersion=12&reWriteBatchedInserts=true username: mda password: mda#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;" statement-cache-size: 250 data-source-properties: prepareThreshold: 3 preparedStatementCacheQueries: 250 # 로컬 배치 메타 DB (signal 스키마 사용) batch: jdbc-url: jdbc:postgresql://10.188.171.182:5432/mdadb?currentSchema=signal&assumeMinServerVersion=12&reWriteBatchedInserts=true username: mda password: mda#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;" # 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: DEBUG gc.mda.signal_batch.global.util: INFO gc.mda.signal_batch.global.websocket.service: INFO gc.mda.signal_batch.batch.writer: INFO gc.mda.signal_batch.batch.reader: INFO gc.mda.signal_batch.batch.processor: INFO gc.mda.signal_batch.domain: INFO gc.mda.signal_batch.monitoring: DEBUG gc.mda.signal_batch.monitoring.controller: INFO org.springframework.batch: INFO org.springframework.jdbc: WARN org.postgresql: WARN com.zaxxer.hikari: INFO # 개발 환경 배치 설정 (성능 최적화) vessel: # spring 하위가 아닌 최상위 레벨 # 통합선박 설정 integration: enabled: true # 통합선박 기능 활성화 여부 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분치 데이터 조회 (수집 지연 고려) # 비정상 궤적 검출 설정 (개선됨) 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_abnormal_tracks: retention-months: 0 # 비정상 항적: 무한 보관 # 일일 항적 데이터 인메모리 캐시 cache: daily-track: enabled: true retention-days: 7 # D-1 ~ D-7 (오늘 제외) max-memory-gb: 5 # 최대 5GB warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음) # WebSocket 부하 제어 설정 websocket: query: max-concurrent-global: 60 # 서버 전체 동시 실행 쿼리 상한 (Query풀 180 / 쿼리당 ~3커넥션) max-per-session: 20 # 세션당 동시 쿼리 상한 (대기열 방식이므로 넉넉하게) queue-timeout-seconds: 30 # 글로벌 대기 큐 타임아웃 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) # 액추에이터 설정 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