Signal Batch - Vessel Signal Batch Aggregation System
빌드 및 실행
# 빌드 (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개)
- CollectDataSource: 원본 신호 수집 (읽기 전용)
- QueryDataSource: 집계 데이터 조회/쓰기
- 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)
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 참조