Initialize RTGS prototype repository
3센터 A-A-A RTGS 실시간총액결제 프로토타입 최초 버전관리 시작. - backend: Kotlin/Gradle 멀티모듈(sequencer, common, 채널/센터 모듈) - frontend: Vite + TS - infra: docker-compose, prometheus/grafana, ELK 네이티브 스크립트 - loadtest(k6), sim(장애/순서/정합성 시나리오), docs(PoC 보고서/복원력방안)
This commit is contained in:
80
docs/RTGS 3센터 이관·기동 체크리스트.md
Normal file
80
docs/RTGS 3센터 이관·기동 체크리스트.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# RTGS 3센터 삼중화 — 이관·기동 체크리스트
|
||||
|
||||
> 대상: 고사양 PC(40코어/128GB) 이관 후 **테스트 시작**용. 코드(B1/B2/B3)·설정공통화·스크립트는
|
||||
> 8코어 PC에서 구현·빌드·단위테스트 완료(2026-07-13). 이 문서대로 기동하면 3센터 실측 가능.
|
||||
|
||||
## 0. 구현 요약 (이번에 반영된 것)
|
||||
| 항목 | 내용 | 파일 |
|
||||
|---|---|---|
|
||||
| B1 무손실 순번기 | SEQUENCE `global_seq_seq` + `journal_outbox`(durable-before-publish) + 재발행 스케줄러 | `sequencer/SequencerService.kt`, `louisvuitton/.../db/migration/V4__seq_outbox.sql` |
|
||||
| B1 리더선출 | 순번기 그룹 `sequencer` 단일 리더(Kafka 리밸런스). **전역 단일 인스턴스 = DC1** | 동상 |
|
||||
| B2 정족수 | `rtgs.result`=applied-ack, `QuorumAggregator`가 센터 집계 → 과반(2/3) ACCC | `prada/QuorumAggregator.kt`, `prada/PradaService.kt` |
|
||||
| B3 gap 타임아웃 | `GapBuffer` + 스케줄러: 정체 시 phantom skip(단일 파티션 근거) + `rtgs.journal.gap.timeout` 지표 | `hermes/GapBuffer.kt`, `hermes/HermesService.kt` |
|
||||
| 설정공통화 | 원장/엣지 groupId 센터접미사(`hermes-DC1`…) 파라미터화, 순번기만 단일 그룹 | dior/hermes/prada/chanel Service |
|
||||
| 이관 스크립트 | `run-dc2/dc3.cmd`, `infra/init-3centers-db.cmd`, `run-dc1.cmd`(3센터 모드 지원) | 루트/infra |
|
||||
|
||||
- 단위테스트: `QuorumAggregatorTest`(6), `GapBufferTest`(6) — `gradlew build` 통과.
|
||||
|
||||
## 1. 이관 검증 (고사양 PC 도착 직후)
|
||||
1. `C:\ai-dev` 트리를 동일 경로로 복사(포터블 무설치 철학 — 경로만 같으면 됨).
|
||||
2. 빌드 확인: `cd C:\ai-dev\workspace\rtgs\backend && gradlew.bat build`
|
||||
- JDK21 고정(`gradle.properties`의 `org.gradle.java.home`)이라 별도 설정 불필요.
|
||||
- 기대: `BUILD SUCCESSFUL`, 단위테스트 12건 통과.
|
||||
3. 단일센터 스모크(선택): `run-dc1.cmd`(기본 count=1, db=rtgs) → Chanel :8091로 1건 이체 → ACCC 확인.
|
||||
|
||||
## 2. 3센터 기동 절차 (순서 중요)
|
||||
```
|
||||
1) 공유 인프라 + DC1(3센터 모드) 기동:
|
||||
set CENTER_COUNT=3 & set POSTGRES_DB=rtgs_dc1 & run-dc1.cmd
|
||||
→ postgres:5433, kafka:9092, 단일 순번기 :8090, DC1 원장/엣지(809x) 기동.
|
||||
|
||||
2) 3개 DB 생성(멱등):
|
||||
infra\init-3centers-db.cmd
|
||||
→ rtgs_dc1/dc2/dc3 (스키마는 각 센터 LouisVuitton의 Flyway가 생성).
|
||||
※ DC1은 이미 기동 중이라 rtgs_dc1은 DC1 LouisVuitton이 마이그레이션함.
|
||||
|
||||
3) DC2 기동: run-dc2.cmd (원장/엣지만, 819x, db=rtgs_dc2)
|
||||
4) DC3 기동: run-dc3.cmd (원장/엣지만, 829x, db=rtgs_dc3)
|
||||
```
|
||||
- **순번기는 전역 단일(DC1 :8090)**. DC2/DC3는 저널(rtgs.journal, 단일 파티션)을 **독립 그룹**으로
|
||||
전량 재생 → 각자 rtgs_dc2/dc3 원장에 동일 상태 도달(결정론적 재생).
|
||||
- 완결: 각 센터 Prada가 `rtgs.result`를 전 센터분 집계 → 서로 다른 센터 **2/3** 도달 시 ACCC.
|
||||
|
||||
## 3. 검증 항목 (§설계서 6장 대응)
|
||||
| 시나리오 | 방법 | 기대 |
|
||||
|---|---|---|
|
||||
| 평상시 3센터 | Chanel(:8091 등)로 이체 N건 | 3 DB의 transfer/account **완전 일치**(총액·상태·순번), 즉시 과반 ACCC |
|
||||
| 1센터 강제종료 | DC3 창 닫기 → 이체 계속 | 남은 2센터 ack=2 → 과반 유지 → **완결 지속**, 이중지급 0 |
|
||||
| 재해센터 복구 | DC3 run-dc3 재기동 | 밀린 저널 따라잡기(earliest 재생) → 잔액 일치 수렴 |
|
||||
| 2센터 종료 | DC2·DC3 종료 → 이체 | ack=1 → 과반 미달 → **ACSP(완결 보류)**, 오처리 0 |
|
||||
| 2센터 복구 | DC2·DC3 재기동 | 따라잡기 후 보류분 **ACCC 재개** |
|
||||
| 순서 gap | (인위적 phantom) | `rtgs.journal.gap.timeout` 증가 + skip 후 진행 재개 |
|
||||
|
||||
**대사(정합성) 확인 쿼리** (psql, 각 DB 반복):
|
||||
```
|
||||
psql -h localhost -p 5433 -U rtgs -d rtgs_dc1 -c "SELECT status,count(*),sum(amount) FROM transfer GROUP BY status ORDER BY status;"
|
||||
psql ... -d rtgs_dc2 -c "동일"
|
||||
psql ... -d rtgs_dc3 -c "동일"
|
||||
-- 3개 결과가 동일해야 함. account 총합도 세 DB 동일해야 함.
|
||||
```
|
||||
|
||||
## 4. 포트·토폴로지 참조
|
||||
| 서비스 | DC1 | DC2 | DC3 | 그룹 |
|
||||
|---|---|---|---|---|
|
||||
| Sequencer | 8090 | (없음) | (없음) | `sequencer`(단일 리더) |
|
||||
| Chanel | 8091 | 8191 | 8291 | `chanel-DCx` |
|
||||
| Dior | 8092 | 8192 | 8292 | `dior-DCx` |
|
||||
| Hermes | 8093 | 8193 | 8293 | `hermes-DCx` |
|
||||
| Prada | 8094 | 8194 | 8294 | `prada-DCx` |
|
||||
| Gucci | 8095 | 8195 | 8295 | (무상태) |
|
||||
| LouisVuitton | 8099 | 8199 | 8299 | (Flyway/관리) |
|
||||
- 공유: PostgreSQL 5433(rtgs_dc1/dc2/dc3), Kafka 9092(단일 파티션 저널), Prometheus 9090, Grafana 3000, ELK.
|
||||
|
||||
## 5. 주의·후속 (테스트 중 확인)
|
||||
- **순번기 HA(선택 검증)**: 리더선출 시연하려면 순번기 인스턴스를 추가 기동하되 **반드시 동일
|
||||
SEQUENCE DB**(POSTGRES_DB=rtgs_dc1)를 바라보게 할 것. 서로 다른 DB면 순번 충돌.
|
||||
- **Gucci 콜백 시드**: `institution_endpoint`가 `localhost:8095`(DC1 Gucci)로 시드됨. 센터별
|
||||
콜백 왕복까지 볼 땐 DC2/DC3 endpoint URL 조정 필요(핵심 정족수 검증엔 무관).
|
||||
- **phantom skip 임계**: `rtgs.gap-timeout-ms`(기본 5000) — 실측 부하에 맞게 조정 가능(env/프로퍼티).
|
||||
- **재발행 grace**: `rtgs.outbox-republish-grace-ms`(기본 3000) — 인라인 발행과의 경합 회피 창.
|
||||
- 21 JVM 동시기동은 고사양 PC 전제. 8코어에선 경량 스모크만 권장.
|
||||
Reference in New Issue
Block a user