# Signal Batch - Vessel Signal Batch Aggregation System ## 빌드 및 실행 ```bash # 빌드 (Maven) mvn clean package -DskipTests # 프로파일별 실행 java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=prod java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=prod-mpr java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=dev java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=local java -jar target/vessel-batch-aggregation.jar --spring.profiles.active=query ``` ## 프로젝트 개요 - **설명**: 선박 항적(Track) 실시간 수집 및 배치 집계 시스템 - **Java**: 17 - **Spring Boot**: 3.2.5 - **DB**: PostgreSQL + PostGIS - **빌드도구**: Maven (pom.xml) ## 프로파일 구성 | 프로파일 | 용도 | 배치 | DataSource | 포트 | |---------|------|-----|-----------|------| | **prod** | 운영환경 | 활성화 | 3개 분리 | 18090 | | **prod-mpr** | 운영환경(MPR) | 활성화 | 3개 분리 | 18090 | | **dev** | 개발환경 | 활성화 | 3개 분리 | 18090 | | **local** | 로컬개발 | 비활성화 | 단일 | 8090 | | **query** | 조회전용 | 비활성화 | 단일 | 8090 | ## 핵심 패키지 구조 ``` gc.mda.signal_batch/ ├── batch/ # 배치 처리 (Job, Processor, Reader, Writer) │ ├── job/ # Job 설정 및 스케줄러 │ ├── reader/ # ItemReader (파티션, 메모리) │ ├── processor/ # ItemProcessor (항적 변환, 비정상 검출) │ ├── writer/ # ItemWriter (Bulk Insert, Upsert) │ └── listener/ # 배치 리스너 ├── domain/ │ ├── gis/ # GIS API (해구, 구역, 타일) │ ├── vessel/ # 선박 항적/위치 조회, 필터링 │ ├── track/ # 비정상 항적 검출 API │ ├── passage/ # 순차 영역 통과 조회 │ ├── ship/ # 선박 이미지 API │ └── debug/ # 디버그 API ├── global/ │ ├── config/ # DataSource, WebSocket, Batch 설정 │ ├── util/ # 공통 유틸리티 │ ├── websocket/ # WebSocket STOMP 스트리밍 │ └── tool/ # 배치 진단 도구 ├── migration/ # 데이터 마이그레이션 └── monitoring/ # 모니터링, 메트릭, 성능 최적화 ``` ## DataSource 구성 (3개) 1. **CollectDataSource**: 원본 신호 수집 (읽기 전용) 2. **QueryDataSource**: 집계 데이터 조회/쓰기 3. **BatchDataSource**: Spring Batch 메타데이터 설정 클래스: - `DevDataSourceConfig.java` (dev) - `ProdDataSourceConfig.java` (prod/prod-mpr) - `LocalDataSourceConfig.java` (local) - `QueryDataSourceConfig.java` (query) ## 주요 API 엔드포인트 ### REST API V1 (WKT 응답) | 메서드 | 경로 | 설명 | |--------|------|------| | GET | `/api/v1/haegu/boundaries` | 해구 경계 | | GET | `/api/v1/haegu/vessel-stats` | 해구별 선박 통계 | | GET | `/api/v1/tracks/haegu/{no}` | 해구별 항적 | | GET | `/api/v1/tracks/area/{areaId}` | 영역별 항적 | | POST | `/api/v1/tracks/vessels` | 선박별 항적 조회 (일괄) | | GET | `/api/v1/vessels/recent-positions` | 최근 위치 업데이트 선박 | ### REST API V2 (JSON/CompactVesselTrack) | 메서드 | 경로 | 설명 | |--------|------|------| | POST | `/api/v2/tracks/vessels` | 선박별 항적 (JSON 배열 응답) | | GET | `/api/v2/tracks/haegu/{no}` | 해구별 항적 (JSON) | ### 비정상 항적 API | 메서드 | 경로 | 설명 | |--------|------|------| | GET | `/api/v1/abnormal-tracks/recent` | 최근 비정상 항적 | | GET | `/api/v1/abnormal-tracks/vessel/{sigSrcCd}/{targetId}` | 특정 선박 비정상 이력 | | GET | `/api/v1/abnormal-tracks/statistics` | 비정상 통계 | | POST | `/api/v1/abnormal-tracks/detect` | 사용자 정의 기준 검출 | ### 기타 API | 메서드 | 경로 | 설명 | |--------|------|------| | POST | `/api/v1/passages/sequential` | 순차 구역 통과 조회 | | GET | `/api/v1/shipimg/{imo}` | 선박 이미지 조회 | | GET | `/api/v1/tiles/{z}/{x}/{y}` | 타일 집계 데이터 | ### WebSocket (STOMP) - **엔드포인트**: `/ws-tracks` (네이티브), `/ws-tracks` + SockJS - **쿼리 요청**: `/app/tracks/query` - **쿼리 취소**: `/app/tracks/cancel/{queryId}` - **응답 수신**: `/user/queue/tracks/response` - **청크 데이터**: `/user/queue/tracks/chunk` - **상태 업데이트**: `/user/queue/tracks/status` ## 배치 Job | Job | Cron | 지연 | 역할 | |-----|------|-----|------| | **incremental** | 매 5분 (3,8,13...) | 3분 | 수집 DB → 위치 집계 | | **track** | 매 5분 (4,9,14...) | 4분 | 위치 → 항적(LineStringM) 변환 | | **hourly** | 매시 10분 | - | 5분 → 시간 집계, 비정상 검출 | | **daily** | 매일 01:00 | - | 시간 → 일 집계, 비정상 검출 | ### 배치 처리 흐름 ``` CollectDB (신호) → incremental Job (5분 버킷 집계) → track Job (LineStringM 항적 생성) → hourly Job (시간 병합 + 비정상 검출) → daily Job (일 병합 + 비정상 검출) ``` ## 코드 스타일 - Lombok 사용 (@Data, @Builder, @Slf4j) - JdbcTemplate 직접 사용 (JPA 미사용) - PostGIS 공간 쿼리 활용 - 청크 기반 배치 처리 (기본 10,000건) - UPSERT/Bulk Insert 최적화 ## 주요 DTO - `CompactVesselTrack`: WebSocket/REST V2 응답 (geometry[], timestamps[], speeds[], nationalCode, shipKindCode) - `TrackResponse`: REST V1 응답 (WKT 기반) - `VesselTracksRequest`: 항적 조회 요청 - `AbnormalTrackResponse`: 비정상 항적 응답 - `SequentialPassageRequest/Response`: 순차 통과 조회 ## 최근 작업 이력 ### 2026-01-20 - V2 REST API 추가 (WebSocket 응답 호환) - `GisControllerV2.java`, `GisServiceV2.java` - CompactVesselTrack 확장: nationalCode, shipKindCode, integrationTargetId 추가 - WebSocket 청크 스트리밍 구현 (`ChunkedTrackStreamingService`) - 선박 최신 위치 캐시 갱신 스케줄러 추가 - DateTime 파싱 유연화 (`FlexibleLocalDateTimeDeserializer`) - Swagger 9개 API 그룹 체계화 ## 주의사항 - 빌드: `mvn` 사용 (Gradle 아님) - 프로파일별 DataSource 설정이 다름 - WebSocket은 STOMP 프로토콜 사용 - LineStringM 형식: `LINESTRING M(lon lat unixTimestamp, ...)` - 비정상 항적 검출: 시간/일 집계 시 자동 수행 ## 성능 설정 (prod) ```yaml batch: chunk-size: 10000 partition-size: 12 fetch-size: 200000 bulk-insert: batch-size: 10000 parallel-threads: 8 cache: latest-position: ttl-minutes: 60 max-size: 60000 abnormal-detection: 5min-speed-threshold: 500 knots hourly-daily-speed-limit: 500 knots ``` ## Swagger 문서 - **접근**: `http://localhost:{port}/swagger-ui.html` - **API 그룹**: 항적조회, 비정상항적, 타일, 선박이미지, 성능최적화, 관리자, 모니터링, 마이그레이션, 디버그 ## 팀 규칙 - 코드 스타일: `.claude/rules/code-style.md` 참조 - 네이밍 규칙: `.claude/rules/naming.md` 참조 - 테스트 규칙: `.claude/rules/testing.md` 참조 - Git 워크플로우: `.claude/rules/git-workflow.md` 참조 - 팀 정책: `.claude/rules/team-policy.md` 참조