From 2838af323b0fd08974920095c798e2c7dd3d7421 Mon Sep 17 00:00:00 2001 From: htlee Date: Thu, 19 Feb 2026 14:30:02 +0900 Subject: [PATCH] =?UTF-8?q?ci:=20Gitea=20Actions=20CI/CD=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=B4=ED=94=84=EB=9D=BC=EC=9D=B8=20+=20systemd=20=EC=84=9C?= =?UTF-8?q?=EB=B9=84=EC=8A=A4=20=EA=B5=AC=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - .gitea/workflows/deploy.yml: main push → 빌드 → SSH 배포 → 헬스체크 - JDK 17 + Maven 빌드, JAR 원자적 교체, 백업 5세대 유지 - 90초 startup 대기 (64GB 힙 AlwaysPreTouch) - deploy/signal-batch.service: systemd 유닛 파일 - 64GB 힙, G1GC 24 병렬스레드, GC 로그 5×100MB 로테이션 - on-failure 자동 재시작, graceful shutdown (SIGTERM 60s) - application-prod.yml: 64코어/250GB 서버 최적화 (파티션 32, 커넥션 풀 정리) - 미사용 프로필 삭제: application-dev.yml, application-prod-mpr.yml, application-query.yml Co-Authored-By: Claude Opus 4.6 --- .gitea/workflows/deploy.yml | 82 +++++ deploy/signal-batch.service | 66 ++++ src/main/resources/application-dev.yml | 265 ---------------- src/main/resources/application-prod-mpr.yml | 319 -------------------- src/main/resources/application-prod.yml | 281 +++++++---------- src/main/resources/application-query.yml | 138 --------- 6 files changed, 261 insertions(+), 890 deletions(-) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 deploy/signal-batch.service delete mode 100644 src/main/resources/application-dev.yml delete mode 100644 src/main/resources/application-prod-mpr.yml delete mode 100644 src/main/resources/application-query.yml diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..d674219 --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,82 @@ +name: Build & Deploy + +on: + push: + branches: [main] + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install JDK 17 + Maven + run: | + apt-get update -qq + apt-get install -y -qq openjdk-17-jdk-headless maven openssh-client > /dev/null 2>&1 + java -version + mvn --version + + - name: Build with Maven + run: | + mvn -B clean package -DskipTests \ + -Dmaven.compiler.release=17 + ls -lh target/vessel-batch-aggregation.jar + + - name: Deploy to production server + env: + DEPLOY_KEY: ${{ secrets.DEPLOY_SSH_KEY }} + run: | + # SSH 키 설정 + mkdir -p ~/.ssh + echo "$DEPLOY_KEY" > ~/.ssh/id_deploy + chmod 600 ~/.ssh/id_deploy + ssh-keyscan -p 32023 192.168.1.18 >> ~/.ssh/known_hosts 2>/dev/null || true + + SSH_CMD="ssh -p 32023 -i ~/.ssh/id_deploy -o StrictHostKeyChecking=no root@192.168.1.18" + SCP_CMD="scp -P 32023 -i ~/.ssh/id_deploy -o StrictHostKeyChecking=no" + + # JAR 전송 + echo "=== Uploading JAR ===" + $SCP_CMD target/vessel-batch-aggregation.jar root@192.168.1.18:/home/apps/signal-batch/vessel-batch-aggregation.jar.new + + # 원자적 교체 + 서비스 재시작 + echo "=== Deploying ===" + $SSH_CMD bash -s << 'DEPLOY' + set -e + APP_DIR=/home/apps/signal-batch + + # 기존 JAR 백업 + if [ -f $APP_DIR/vessel-batch-aggregation.jar ]; then + cp $APP_DIR/vessel-batch-aggregation.jar $APP_DIR/backup/vessel-batch-aggregation.jar.$(date +%Y%m%d-%H%M%S) + fi + + # 원자적 교체 + mv $APP_DIR/vessel-batch-aggregation.jar.new $APP_DIR/vessel-batch-aggregation.jar + + # 백업 정리 (최근 5개만 유지) + ls -t $APP_DIR/backup/vessel-batch-aggregation.jar.* 2>/dev/null | tail -n +6 | xargs rm -f 2>/dev/null || true + + # 서비스 재시작 + systemctl restart signal-batch + echo "Service restarted, waiting for startup..." + + # 시작 확인 (최대 90초 — 48GB 힙 AlwaysPreTouch) + for i in $(seq 1 90); do + if curl -sf http://localhost:18090/actuator/health > /dev/null 2>&1; then + echo "Service started successfully (${i}s)" + curl -s http://localhost:18090/actuator/health + exit 0 + fi + sleep 1 + done + + echo "WARNING: Startup timeout. Recent logs:" + journalctl -u signal-batch --no-pager -n 50 + exit 1 + DEPLOY + + - name: Cleanup + if: always() + run: rm -f ~/.ssh/id_deploy diff --git a/deploy/signal-batch.service b/deploy/signal-batch.service new file mode 100644 index 0000000..34704e8 --- /dev/null +++ b/deploy/signal-batch.service @@ -0,0 +1,66 @@ +[Unit] +Description=Signal Batch Aggregation Service +After=network.target +Wants=network-online.target + +[Service] +Type=simple +User=root +WorkingDirectory=/home/apps/signal-batch + +# JDK 경로 (프로세스별 독립 JDK) +Environment=JAVA_HOME=/home/apps/jdk/jdk-17.0.14+7 + +# Spring Profile +Environment=SPRING_PROFILES_ACTIVE=prod + +# JVM 옵션 — 64코어 Xeon Gold 6430, 250GB RAM +# Heap: 64GB (RAM의 ~26%, 인메모리 캐시 대량 활용) +Environment=JAVA_OPTS="\ +-Xms64g -Xmx64g \ +-XX:+UseG1GC \ +-XX:G1HeapRegionSize=32m \ +-XX:MaxGCPauseMillis=200 \ +-XX:InitiatingHeapOccupancyPercent=35 \ +-XX:G1ReservePercent=15 \ +-XX:G1MixedGCCountTarget=8 \ +-XX:ParallelGCThreads=24 \ +-XX:ConcGCThreads=8 \ +-XX:+UseStringDeduplication \ +-XX:+ParallelRefProcEnabled \ +-XX:+AlwaysPreTouch \ +-XX:MaxMetaspaceSize=512m \ +-XX:+HeapDumpOnOutOfMemoryError \ +-XX:HeapDumpPath=/home/apps/signal-batch/logs/heapdump.hprof \ +-XX:+ExitOnOutOfMemoryError \ +-Xlog:gc*,gc+ref=debug,gc+heap=debug,gc+age=trace:file=/home/apps/signal-batch/logs/gc.log:time,uptime,level,tags:filecount=5,filesize=100m \ +-Dfile.encoding=UTF-8 \ +-Duser.timezone=Asia/Seoul \ +-Djava.security.egd=file:/dev/./urandom" + +ExecStart=/home/apps/jdk/jdk-17.0.14+7/bin/java \ + ${JAVA_OPTS} \ + -jar /home/apps/signal-batch/vessel-batch-aggregation.jar \ + --spring.profiles.active=${SPRING_PROFILES_ACTIVE} + +# Graceful shutdown (SIGTERM → Spring Boot shutdown hook) +ExecStop=/bin/kill -TERM $MAINPID +TimeoutStopSec=60 +KillMode=mixed +KillSignal=SIGTERM + +# 자동 재시작 (OOM 등 비정상 종료 시) +Restart=on-failure +RestartSec=15 + +# 로그 → journald + 파일 (Spring Boot logback) +StandardOutput=journal +StandardError=journal +SyslogIdentifier=signal-batch + +# 리소스 제한 +LimitNOFILE=65536 +LimitNPROC=4096 + +[Install] +WantedBy=multi-user.target diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml deleted file mode 100644 index b3f9177..0000000 --- a/src/main/resources/application-dev.yml +++ /dev/null @@ -1,265 +0,0 @@ -server: - port: 8090 - 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: 20 # 10 -> 20 증가 - minimum-idle: 5 # 2 -> 5 증가 - # 원격 연결 안정성을 위한 추가 설정 - 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 (수집 DB와 동일하게 설정) - query: - jdbc-url: jdbc:postgresql://10.188.141.124: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: QueryHikariPool - connection-timeout: 5000 - idle-timeout: 600000 - max-lifetime: 1800000 - maximum-pool-size: 60 # 20 -> 40 증가 - minimum-idle: 10 # 5 -> 10 증가 - 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;" - statement-cache-size: 250 - data-source-properties: - prepareThreshold: 3 - preparedStatementCacheQueries: 250 - - # 로컬 배치 메타 DB - batch: - jdbc-url: jdbc:postgresql://10.188.141.124:5432/mdadb?currentSchema=public&assumeMinServerVersion=12&reWriteBatchedInserts=true - username: mda - password: mda#8932 - driver-class-name: org.postgresql.Driver - hikari: - pool-name: BatchHikariPool - maximum-pool-size: 20 # 10 → 30 증가 - minimum-idle: 10 # 2 → 10 증가 - 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 public, signal;" - - # 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: 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 # queryDB signal.t_ship_integration_sub 사용 (기본값) - 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: 30 # 보존 기간 (30일) - dry-run: false # false: 실제 삭제, true: 테스트만 - - # 궤적 비정상 검출 설정 - track: - abnormal-detection: - large-gap-threshold-hours: 6 # 이 시간 이상 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: 80000 # 최대 50,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: false # 비정상 구간 제거 여부 - save-corrected-tracks: true # 보정된 궤적 저장 여부 - exclude-stationary-vessels: true # 정박 선박 제외 여부 - lenient-mode: true # 관대한 모드 활성화 - -# S&P AIS API 캐시 TTL (개발: 60분) -app: - cache: - ais-target: - ttl-minutes: 60 - -# 액추에이터 설정 -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: dev \ No newline at end of file diff --git a/src/main/resources/application-prod-mpr.yml b/src/main/resources/application-prod-mpr.yml deleted file mode 100644 index a476aea..0000000 --- a/src/main/resources/application-prod-mpr.yml +++ /dev/null @@ -1,319 +0,0 @@ -server: - port: 8090 - 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.26.252.39: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: 30 # 10 -> 30 증가 - minimum-idle: 10 # 2 -> 10 증가 - # 원격 연결 안정성을 위한 추가 설정 - 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.29.17.90:5432/mpcdb2?currentSchema=signal&assumeMinServerVersion=12&reWriteBatchedInserts=true - username: mpc - password: mpc#8932 - driver-class-name: org.postgresql.Driver - hikari: - pool-name: QueryHikariPool - connection-timeout: 5000 - idle-timeout: 600000 - max-lifetime: 1800000 - maximum-pool-size: 90 # 20 -> 90 증가 - minimum-idle: 15 # 5 -> 15 증가 - 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 - batch: - jdbc-url: jdbc:postgresql://10.26.252.51:5432/mdadb?currentSchema=public&assumeMinServerVersion=12&reWriteBatchedInserts=true - username: mda - password: mda#8932 - driver-class-name: org.postgresql.Driver - hikari: - pool-name: BatchHikariPool - maximum-pool-size: 20 # 10 → 30 증가 - minimum-idle: 10 # 2 → 10 증가 - 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 public, signal;" - - # 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: 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: 30 # 보존 기간 (30일) - dry-run: false # false: 실제 삭제, true: 테스트만 - - # 궤적 비정상 검출 설정 - track: - abnormal-detection: - large-gap-threshold-hours: 6 # 이 시간 이상 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: 50000 # 최대 50,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: false # 비정상 구간 제거 여부 - save-corrected-tracks: true # 보정된 궤적 저장 여부 - exclude-stationary-vessels: true # 정박 선박 제외 여부 - 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 # 비정상 항적: 무한 보관 - -# S&P AIS API 캐시 TTL (운영 MPR: 120분) -app: - cache: - ais-target: - ttl-minutes: 120 - -# 일일 항적 데이터 인메모리 캐시 -cache: - daily-track: - enabled: true - retention-days: 7 # D-1 ~ D-7 (오늘 제외) - max-memory-gb: 6 # 최대 6GB - warmup-async: true # 비동기 워밍업 (배치 Job과 경합 방지) - -# WebSocket 부하 제어 설정 -websocket: - query: - max-concurrent-global: 20 # 배치 서버 동시 쿼리 제한 (메모리 보호: 40→20) - max-per-session: 10 # 세션당 동시 쿼리 상한 (15→10) - queue-timeout-seconds: 60 # 글로벌 대기 큐 타임아웃 (슬롯 감소 보완: 30→60) - transport: - message-size-limit-mb: 2 # 단일 STOMP 메시지 상한 (50→2MB, 청크 1024KB 기준) - send-buffer-size-limit-mb: 50 # 세션당 송신 버퍼 상한 (사전 할당 아님, 최악 20×50MB=1GB) - 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 - server-heartbeat-ms: 5000 - client-heartbeat-ms: 5000 - sockjs-disconnect-delay-ms: 5000 - send-time-limit-seconds: 30 - -# 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 \ No newline at end of file diff --git a/src/main/resources/application-prod.yml b/src/main/resources/application-prod.yml index ebe3e3a..b939b97 100644 --- a/src/main/resources/application-prod.yml +++ b/src/main/resources/application-prod.yml @@ -1,322 +1,267 @@ +# ============================================================================= +# Production Profile — 192.168.1.18 (64코어 Xeon Gold 6430, 250GB RAM) +# DB: snpdb @ 211.208.115.83 (signal 스키마) +# ============================================================================= + 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 # 대기열 크기 + connection-timeout: 60000 + 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 + 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 # 원격 연결이므로 타임아웃 증가 + maximum-pool-size: 50 + minimum-idle: 10 + 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초) + leak-detection-threshold: 60000 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 + 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 + maximum-pool-size: 100 + minimum-idle: 20 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에 명시적으로 추가 + leak-detection-threshold: 60000 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 + 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초 타임아웃 + maximum-pool-size: 20 + minimum-idle: 5 + connection-timeout: 30000 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;" + leak-detection-threshold: 60000 + connection-init-sql: "SET TIME ZONE 'Asia/Seoul'; SET search_path TO public, signal;" - # 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_ + initialize-schema: always + table-prefix: 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: INFO + gc.mda.signal_batch.global.util: WARN + gc.mda.signal_batch.global.util.PartitionManager: WARN + gc.mda.signal_batch.batch: INFO gc.mda.signal_batch.domain: INFO - gc.mda.signal_batch.monitoring: DEBUG - gc.mda.signal_batch.monitoring.controller: INFO + gc.mda.signal_batch.monitoring: INFO org.springframework.batch: INFO org.springframework.jdbc: WARN org.postgresql: WARN com.zaxxer.hikari: INFO -# 개발 환경 배치 설정 (성능 최적화) -vessel: # spring 하위가 아닌 최상위 레벨 - # 통합선박 설정 - integration: - enabled: true - datasource: - jdbc-url: jdbc:postgresql://10.188.141.230:5432/mdadb2?currentSchema=gis&options=-csearch_path=gis,public&TimeZone=Asia/Seoul - username: mda - password: mda#8932 - table-name: gis.t_ship_integration_sub # gis 스키마는 jdbc-url의 currentSchema로 지정 +# ── 배치 설정 (64코어 최적화) ── +vessel: batch: - # Area Statistics 처리를 위한 별도 설정 - area-statistics: - chunk-size: 1000 # 5000 → 1000 - batch-size: 500 # 새로 추가 + scheduler: + enabled: true + incremental: + delay-minutes: 3 chunk-size: 10000 page-size: 5000 - partition-size: 12 + partition-size: 32 + fetch-size: 200000 + use-cursor-reader: true + query-timeout: 1800 + + area-statistics: + chunk-size: 1000 + batch-size: 500 - # 성능 최적화 설정 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 + parallel-threads: 16 use-binary-copy: false - # Writer 설정 writer: use-advisory-lock: false - parallel-threads: 4 + parallel-threads: 8 - # 재시도 설정 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: 테스트만 + enabled: true + retention-days: 21 + dry-run: false - # 궤적 비정상 검출 설정 track: abnormal-detection: - large-gap-threshold-hours: 4 # 이 시간 이상 gap은 연결 안함 - extreme-speed-threshold: 1000 # 이 속도 이상은 무조건 비정상 (knots) - enable-merger-filtering: false # VesselTrackMerger 필터링 활성화 (기본: false) + large-gap-threshold-hours: 4 + extreme-speed-threshold: 1000 + enable-merger-filtering: 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분치 데이터 조회 (수집 지연 고려) + enabled: true + ttl-minutes: 60 + max-size: 60000 + refresh-interval-minutes: 2 - - # 비정상 궤적 검출 설정 (개선됨) abnormal-detection: enabled: true - 5min-speed-threshold: 500 # 5분 집계 비정상 속도 임계값 (200 knots로 완화) - # 비정상 판정 기준 (명백한 비정상만 검출하도록 완화) + 5min-speed-threshold: 500 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) - # 캐시 설정 + 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 + extreme-distance-5min-nm: 100.0 + hourly-daily-speed-limit: 500.0 + distance-tolerance: 3.0 + time-scaling-method: "sqrt" cache: - previous-track-size: 10000 # 이전 궤적 캐시 크기 - ttl-hours: 24 # 캐시 TTL - # 처리 옵션 + previous-track-size: 10000 + ttl-hours: 24 processing: - remove-abnormal-segments: true # 비정상 구간 제거 여부 - save-corrected-tracks: true # 보정된 궤적 저장 여부 - exclude-stationary-vessels: false # 정박 선박 제외 여부 - lenient-mode: true # 관대한 모드 활성화 + 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개월 보관 - + daily-partitions-retention-days: 7 + monthly-partitions-retention-months: 3 tables: - # 중요 데이터는 더 오래 보관 t_area_vessel_tracks: - retention-days: 60 # 구역별 선박 항적: 60일 + retention-days: 60 t_grid_vessel_tracks: - retention-days: 30 # 해구별 선박 항적: 30일 + retention-days: 30 t_abnormal_tracks: - retention-months: 0 # 비정상 항적: 무한 보관 + retention-months: 0 -# S&P AIS API 캐시 TTL (운영: 120분) +# ── AIS API ── app: + ais-api: + username: 7cc0517d-5ed6-452e-a06f-5bbfd6ab6ade + password: 2LLzSJNqtxWVD8zC + cache: ais-target: ttl-minutes: 120 - five-min-track: ttl-minutes: 75 max-size: 500000 - hourly-track: ttl-hours: 26 max-size: 780000 -# 일일 항적 데이터 인메모리 캐시 +# ── 일일 항적 인메모리 캐시 (250GB 서버, 힙 64GB) ── cache: daily-track: enabled: true - retention-days: 7 # D-1 ~ D-7 (오늘 제외) - max-memory-gb: 6 # 최대 6GB (일 평균 ~720MB × 7일 = ~5GB) - warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음) + retention-days: 7 + max-memory-gb: 16 + warmup-async: true -# WebSocket 부하 제어 설정 +# ── WebSocket 부하 제어 ── websocket: query: - max-concurrent-global: 30 # 서버 전체 동시 실행 쿼리 상한 (메모리 보호: 60→30) - max-per-session: 10 # 세션당 동시 쿼리 상한 (20→10) - queue-timeout-seconds: 60 # 글로벌 대기 큐 타임아웃 (슬롯 감소 보완: 30→60) + max-concurrent-global: 30 + max-per-session: 10 + queue-timeout-seconds: 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 # 메시지 전송 시간 제한 + message-size-limit-mb: 2 + send-buffer-size-limit-mb: 50 + outbound-queue-capacity: 200 + send-time-limit-seconds: 30 memory: - heap-reject-threshold: 0.85 # 힙 사용률 85% 초과 시 새 쿼리 대기열 전환 (기본 20~24GB → 정상시 50% 미만) + heap-reject-threshold: 0.85 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) + idle-timeout-ms: 15000 + server-heartbeat-ms: 5000 + client-heartbeat-ms: 5000 + sockjs-disconnect-delay-ms: 5000 + send-time-limit-seconds: 30 -# REST V2 부하 제어 설정 +# ── REST V2 부하 제어 ── rest: v2: query: - timeout-seconds: 30 # 슬롯 대기 타임아웃 (초) - max-total-points: 500000 # 응답 총 포인트 상한 + timeout-seconds: 30 + max-total-points: 500000 -# 액추에이터 설정 +# ── 액추에이터 ── management: endpoints: web: @@ -329,4 +274,4 @@ management: metrics: tags: application: vessel-batch-aggregation - environment: prod \ No newline at end of file + environment: prod diff --git a/src/main/resources/application-query.yml b/src/main/resources/application-query.yml deleted file mode 100644 index eb8485b..0000000 --- a/src/main/resources/application-query.yml +++ /dev/null @@ -1,138 +0,0 @@ -# 조회 전용 서버 설정 (10.29.17.90) -# 배치 작업 없이 API 조회만 수행하는 프로파일 -server: - port: 8090 - tomcat: - threads: - max: 200 - min-spare: 10 - connection-timeout: 60000 - max-http-form-post-size: 50MB - max-swallow-size: 50MB - max-connections: 10000 - accept-count: 100 - -spring: - datasource: - # 조회 전용 DB (10.29.17.90 로컬 DB) - 표준 Spring Boot DataSource 설정 - url: jdbc:postgresql://localhost:5432/mpcdb2?currentSchema=signal&options=-csearch_path=signal,public&assumeMinServerVersion=12&reWriteBatchedInserts=true - username: mpc - password: mpc#8932 - driver-class-name: org.postgresql.Driver - hikari: - pool-name: QueryOnlyHikariPool - connection-timeout: 5000 - idle-timeout: 600000 - max-lifetime: 1800000 - maximum-pool-size: 60 - minimum-idle: 10 - connection-test-query: SELECT 1 - validation-timeout: 5000 - leak-detection-threshold: 60000 - connection-init-sql: "SET TIME ZONE 'Asia/Seoul'; SET search_path TO signal, public;" - data-source-properties: - prepareThreshold: 3 - preparedStatementCacheQueries: 250 - - # Request 크기 설정 - servlet: - multipart: - max-file-size: 50MB - max-request-size: 50MB - - # Spring Batch 자동 구성 완전 비활성화 - autoconfigure: - exclude: - - org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration - - # Spring Batch Job 비활성화 - batch: - job: - enabled: false - jdbc: - initialize-schema: never - -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: WARN # 배치 관련 로그 최소화 - gc.mda.signal_batch.domain: INFO - gc.mda.signal_batch.monitoring: DEBUG - gc.mda.signal_batch.monitoring.controller: INFO - org.springframework.batch: WARN # 배치 관련 로그 최소화 - org.springframework.jdbc: WARN - org.postgresql: WARN - com.zaxxer.hikari: INFO - -# 배치 설정 (조회 전용 서버에서는 사용 안 함) -vessel: - # 통합선박 기능 비활성화 (query DB에 통합테이블이 없을 수 있음) - integration: - enabled: false - - batch: - # 스케줄러 비활성화 (중요!) - scheduler: - enabled: false - incremental: - delay-minutes: 3 - - # 비정상 궤적 검출 비활성화 - abnormal-detection: - enabled: false - - # 기타 배치 설정은 사용되지 않지만 기본값 유지 - chunk-size: 10000 - page-size: 5000 - partition-size: 12 - -# 일일 항적 데이터 인메모리 캐시 (조회 전용 서버의 핵심 성능 설정) -cache: - daily-track: - enabled: true - retention-days: 7 # D-1 ~ D-7 (오늘 제외) - max-memory-gb: 6 # 최대 6GB (조회 전용이므로 배치 없이 메모리 여유) - warmup-async: true # 비동기 워밍업 (서버 시작 차단 없음) - -# WebSocket 부하 제어 설정 -websocket: - query: - max-concurrent-global: 40 # 조회 전용 서버 (배치 없으므로 prod-mpr보다 여유) - max-per-session: 15 # 세션당 동시 쿼리 상한 - queue-timeout-seconds: 30 # 글로벌 대기 큐 타임아웃 - transport: - message-size-limit-mb: 2 # 단일 STOMP 메시지 상한 (청크 1024KB 기준) - send-buffer-size-limit-mb: 50 # 세션당 송신 버퍼 상한 (사전 할당 아님, 최악 40×50MB=2GB) - outbound-queue-capacity: 200 # 아웃바운드 메시지 큐 - send-time-limit-seconds: 30 # 메시지 전송 시간 제한 - session: - idle-timeout-ms: 15000 - server-heartbeat-ms: 5000 - client-heartbeat-ms: 5000 - sockjs-disconnect-delay-ms: 5000 - send-time-limit-seconds: 30 - -# 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 - endpoint: - health: - show-details: always - show-components: always - metrics: - tags: - application: vessel-query-server - environment: query