200 lines
7.9 KiB
Markdown
200 lines
7.9 KiB
Markdown
SNP Sync Batch
|
|
|
|
S&P Global 해양 데이터를 수집하여 PostgreSQL에 동기화하는 Spring Batch 시스템입니다.
|
|
|
|
## 기술 스택
|
|
|
|
| 구분 | 기술 |
|
|
|------|------|
|
|
| Language | Java 17 |
|
|
| Framework | Spring Boot 3.2.1, Spring Batch 5.1.0 |
|
|
| Scheduler | Quartz 2.5.0 (JDBC Store) |
|
|
| Database | PostgreSQL (dual datasource) |
|
|
| Cache | Caffeine |
|
|
| Frontend | React + TypeScript (Vite) |
|
|
| Build | Maven (frontend-maven-plugin 통합) |
|
|
| CI/CD | Gitea Actions → systemd 자동 배포 |
|
|
|
|
## 아키텍처
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|
│ SNP Sync Batch │
|
|
│ │
|
|
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
│ │ Quartz │───►│ Reader │───►│ Processor │───►│ Writer │ │
|
|
│ │ Scheduler │ │(BaseSyncR)│ │(DTO→Entity)│ │(SubChunk) │ │
|
|
│ └──────────┘ └────┬─────┘ └──────────┘ └────┬─────┘ │
|
|
│ │ │ │
|
|
│ ┌────────▼────────┐ ┌───────▼───────┐ │
|
|
│ │ Source DB │ │ Target DB │ │
|
|
│ │ (std_snp_data) │ │ (std_snp_svc) │ │
|
|
│ │ batch_flag 관리 │ │ UPSERT 저장 │ │
|
|
│ └─────────────────┘ └───────────────┘ │
|
|
│ │
|
|
│ ┌──────────────────────────────────────────────────────────┐ │
|
|
│ │ React Frontend (포트 8051, /snp-sync) │ │
|
|
│ │ 대시보드 │ 동기화현황 │ 실행이력 │ 스케줄 │ 타임라인 │ │
|
|
│ └──────────────────────────────────────────────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
## 데이터베이스 구조
|
|
|
|
### Dual Datasource
|
|
|
|
| Datasource | 스키마 | 용도 |
|
|
|------------|--------|------|
|
|
| batchDataSource (Primary) | snp_batch | Spring Batch 메타데이터, Quartz 스케줄 |
|
|
| businessDataSource | std_snp_data / std_snp_svc | 비즈니스 데이터 (소스/타겟) |
|
|
|
|
### 동기화 대상 테이블
|
|
|
|
| 도메인 | 소스 테이블 수 | 주요 내용 |
|
|
|--------|--------------|----------|
|
|
| Ship | 25개 | 선박 제원, 이력, 관계 |
|
|
| Company | 1개 | 회사 상세 정보 |
|
|
| Event | 4개 | 해양 사건/사고 |
|
|
| Facility | 1개 | 항구 시설 |
|
|
| PSC | 3개 | PSC 검사 |
|
|
| Movements | 8개 | 선박 이동 (항적) |
|
|
| Code | 2개 | 코드 (선종, 국적) |
|
|
| Risk | 1개 | 위험 지표 (+ 값 변경 이력) |
|
|
| Compliance | 2개 | 컴플라이언스 (+ 값 변경 이력) |
|
|
|
|
## 동기화 프로세스
|
|
|
|
### batch_flag 상태 흐름
|
|
|
|
```
|
|
[N] 대기 ──── Reader ────► [P] 진행 ──── Writer 성공 ────► [S] 완료
|
|
│ │
|
|
│ Writer 실패 시
|
|
│ P 상태 고착 (수동 리셋 필요)
|
|
│
|
|
batch_job_execution.status = 'COMPLETED' 인 데이터만 대상
|
|
```
|
|
|
|
### Reader → Writer 흐름
|
|
|
|
```
|
|
BaseSyncReader (while 루프)
|
|
│
|
|
├─ fetchNextGroup(11284): MIN(batch_flag='N') → 데이터 로드 → N→P
|
|
├─ fetchNextGroup(11286): 다음 그룹 연속 로드 → N→P
|
|
├─ fetchNextGroup(11317): 다음 그룹 연속 로드 → N→P
|
|
└─ fetchNextGroup(): 데이터 없음 → return null → Step 종료
|
|
│
|
|
▼
|
|
BaseChunkedWriter (sub-chunk 5000건 단위)
|
|
│
|
|
├─ Sub-Chunk 1: [1~5000건] → 독립 트랜잭션 커밋
|
|
├─ Sub-Chunk 2: [5001~10000건] → 독립 트랜잭션 커밋
|
|
└─ ...
|
|
│
|
|
▼
|
|
BatchWriteListener.afterWrite()
|
|
└─ 청크 내 모든 고유 job_execution_id → P→S 업데이트
|
|
```
|
|
|
|
### 값 변경 이력 관리 (Risk, Compliance)
|
|
|
|
데이터 동기화 Job과 값 변경 이력 Job이 분리되어 운영됩니다:
|
|
|
|
```
|
|
riskDataSyncJob (데이터 동기화)
|
|
Source → Reader → Writer
|
|
├─ UPSERT → tb_ship_risk_detail_info (최신 데이터)
|
|
└─ UPSERT → tb_ship_risk_detail_hstry (스냅샷 이력)
|
|
|
|
riskDetailChangeDataSyncJob (값 변경 이력)
|
|
tb_ship_risk_detail_hstry (스냅샷)
|
|
→ imo_no별 시계열 비교
|
|
→ indicator 컬럼 변경분 감지
|
|
→ INSERT → tb_ship_risk_detail_info_hstry (컬럼명, 이전값, 이후값)
|
|
```
|
|
|
|
## 배치 Job 목록
|
|
|
|
### 데이터 동기화 Job
|
|
|
|
| Job 이름 | 도메인 | 설명 |
|
|
|----------|--------|------|
|
|
| snpMdaDataSyncJob | Ship + Company | 선박/회사 데이터 동기화 (26 Step) |
|
|
| eventDataSyncJob | Event | 사건 데이터 동기화 (4 Step) |
|
|
| facilitySyncJob | Facility | 항구 시설 동기화 |
|
|
| pscDataSyncJob | PSC | PSC 검사 동기화 (3 Step) |
|
|
| anchorageCallDataSyncJob | Movements | 정박지 기항 |
|
|
| berthCallDataSyncJob | Movements | 부두 기항 |
|
|
| currentlyAtDataSyncJob | Movements | 현재 위치 |
|
|
| destinationDataSyncJob | Movements | 목적지 |
|
|
| portCallDataSyncJob | Movements | 항구 기항 |
|
|
| stsOperationDataSyncJob | Movements | STS 작업 |
|
|
| terminalCallDataSyncJob | Movements | 터미널 기항 |
|
|
| transitDataSyncJob | Movements | 통과 |
|
|
| codeDataSyncJob | Code | 코드 동기화 (2 Step) |
|
|
| riskDataSyncJob | Risk | 위험 지표 동기화 |
|
|
| shipComplianceDataSyncJob | Compliance | 선박 컴플라이언스 |
|
|
| companyComplianceDataSyncJob | Compliance | 회사 컴플라이언스 |
|
|
|
|
### 값 변경 이력 Job
|
|
|
|
| Job 이름 | 설명 |
|
|
|----------|------|
|
|
| riskDetailChangeDataSyncJob | Risk indicator 값 변경 이력 |
|
|
| shipComplianceChangeDataSyncJob | 선박 컴플라이언스 값 변경 이력 |
|
|
| companyComplianceChangeDataSyncJob | 회사 컴플라이언스 값 변경 이력 |
|
|
|
|
### 유지보수 Job
|
|
|
|
| Job 이름 | 설명 |
|
|
|----------|------|
|
|
| batchLogCleanupJob | 배치 로그 정리 (90일 보관) |
|
|
|
|
## 프론트엔드
|
|
|
|
| 메뉴 | 경로 | 설명 |
|
|
|------|------|------|
|
|
| 대시보드 | `/` | 통계, 실행 중 작업, 최근 실행/실패 |
|
|
| 동기화 현황 | `/sync-status` | 테이블별 N/P/S 건수, 데이터 미리보기, P 리셋 |
|
|
| 실행 이력 | `/executions` | 배치 실행 검색, 필터, 상세 |
|
|
| 작업 | `/jobs` | Job 목록, 수동 실행 |
|
|
| 스케줄 | `/schedules` | Quartz 스케줄 CRUD, Cron 미리보기 |
|
|
| 타임라인 | `/schedule-timeline` | 일/주/월별 실행 시각화 |
|
|
|
|
## CI/CD
|
|
|
|
```
|
|
develop → main 머지
|
|
→ Gitea Actions (빌드 + JAR 배포)
|
|
→ systemd path watcher (.deploy-trigger 감지)
|
|
→ restart.sh → 서비스 재시작
|
|
```
|
|
|
|
### 배포 확인
|
|
|
|
```bash
|
|
# 배포 로그
|
|
cat /devdata/services/snp-sync-batch/backend/deploy.log
|
|
|
|
# 서비스 상태
|
|
systemctl status snp-sync-batch
|
|
|
|
# 실시간 로그
|
|
journalctl -u snp-sync-batch -n 100 -f
|
|
```
|
|
|
|
## 빌드 및 실행
|
|
|
|
```bash
|
|
# 개발 환경 실행
|
|
mvn spring-boot:run
|
|
|
|
# 패키징
|
|
mvn clean package -DskipTests
|
|
|
|
# 서버 포트: 8051
|
|
# Context Path: /snp-sync
|
|
# Swagger: /snp-sync/swagger-ui.html
|
|
```
|