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:
186
docs/RTGS 프로토타입 워크플로우.md
Normal file
186
docs/RTGS 프로토타입 워크플로우.md
Normal file
@@ -0,0 +1,186 @@
|
||||
# RTGS 프로토타입 워크플로우
|
||||
|
||||
> 로컬(1센터 DC1) RTGS 프로토타입의 전문 처리 흐름 · 서비스별 처리 · 데이터 흐름 정리
|
||||
> 작성: 루비 · 담당: 양팀장님
|
||||
|
||||
---
|
||||
|
||||
## 1. 시스템 구성도
|
||||
|
||||
```
|
||||
[참가기관 / 부하생성기(k6) / 조회·신청 콘솔(:5174)]
|
||||
│ pacs.008 (HTTP, XML)
|
||||
▼
|
||||
┌──────────────────────────── 1센터 (CENTER_ID=DC1) ────────────────────────────┐
|
||||
│ │
|
||||
│ ① Chanel(전문송수신) :8091 │
|
||||
│ XSD검증 → 경량명령문(75B)+원전문해시 → 원전문 저장 → 입구 발행 → pacs.002 응답 │
|
||||
│ │ rtgs.inbound └→ raw_message(PostgreSQL) │
|
||||
│ ▼ │
|
||||
│ ③ Sequencer(순번기) :8090 전역순번 부여 + 결정론적값 확정 → 저널 발행 │
|
||||
│ │ rtgs.journal (단일 파티션 = 전역 순서) │
|
||||
│ ├───────────────┬───────────────────────────┐ │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ Dior(접수동기화) Hermes(결제/원장엔진, cc=1) (저널 구독) │
|
||||
│ PDNG 기록 순차소비→선저널→잔액이체→ACSP→결과발행 │
|
||||
│ │ │ rtgs.result │
|
||||
│ │ ▼ │
|
||||
│ │ Prada(결과동기화) 과반확정→ACCC 최종확정 │
|
||||
│ ▼ ▼ ▼ │
|
||||
│ ┌──────────────── PostgreSQL(:5433, 강한 일관성 원장) ────────────────┐ │
|
||||
│ │ account(잔액) · transfer(거래상태) · journal_log(선저널) · │ │
|
||||
│ │ settlement_view(조회사본) · raw_message(원전문) · app_user │ │
|
||||
│ └────────────────────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ⑥ LouisVuitton(관리자) :8099 초기화·코드·사용자·대사 (← 콘솔 관리자 탭)
|
||||
│ ⑦ Gucci(외부 경계 관문) :8095 로그인·API인증·유량제어·재전송차단·결과콜백송부(→참가기관) │
|
||||
└────────────────────────────────────────────────────────────────────────────────┘
|
||||
|
||||
로그: 각 서비스(Logback) ──TCP:5000──▶ Logstash ──▶ Elasticsearch(:9200) ──▶ Kibana(:5601)
|
||||
메시지: Kafka(:9092, KRaft) 토픽: rtgs.inbound / rtgs.journal / rtgs.result / rtgs.notify
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. 자금이체 처리 워크플로우 (핵심)
|
||||
|
||||
### 흐름 요약
|
||||
```
|
||||
[신청] ORG_S가 pacs.008 전송
|
||||
└▶ [접수] Chanel : XSD검증·경량화·원전문저장 → 상태 RCVD → rtgs.inbound
|
||||
└▶ [순번] Sequencer : 전역순번+결정론적값 → 상태 ACTC → rtgs.journal(저널)
|
||||
├▶ [접수동기화] Dior : 저널 소비 → PostgreSQL 원장에 PDNG 기록
|
||||
└▶ [청산·정산] Hermes : 저널 순차소비(cc=1)
|
||||
→ gap/역전 탐지·재정렬 → 선저널(write-ahead)
|
||||
→ 송신기관 당좌 −금액 / 수신기관 당좌 +금액 (강한 일관성 트랜잭션)
|
||||
→ 상태 ACSP → (커밋 후) rtgs.result 발행
|
||||
└▶ [결과동기화] Prada : 결과 소비 → 과반(2/3) 확정
|
||||
→ 상태 ACCC(입금처리완료) 최종확정 + 조회사본 기록
|
||||
→ (커밋 후) rtgs.notify 발행
|
||||
└▶ [결과통보] Chanel(접수센터) : rtgs.notify 소비 → 최종 pacs.002 생성
|
||||
→ 신청기관(송신) 앞 결과통보 + 수취기관 앞 입금통보(ACCC) → notification 아웃박스
|
||||
```
|
||||
|
||||
### 단계별 상세 (각 서비스가 다루는 토픽/DB)
|
||||
|
||||
| 순서 | 서비스 | 입력 | 처리 | 출력 | 상태 |
|
||||
|---|---|---|---|---|---|
|
||||
| ① | **Chanel** | HTTP pacs.008 | XSD검증→경량명령문+원전문해시, 원전문 저장 | `raw_message` 저장, `rtgs.inbound` 발행, pacs.002 응답 | RCVD |
|
||||
| ② | **Sequencer** | `rtgs.inbound` | 전역순번 부여 + 결정론적값(수신시각) 확정 | `rtgs.journal` 발행(저널) | ACTC |
|
||||
| ③ | **Dior** | `rtgs.journal` | BMI 중복체크(upsert) | `transfer` PDNG 기록 | PDNG |
|
||||
| ④ | **Hermes** | `rtgs.journal`(cc=1 순차) | 순서 탐지·교정 → 선저널 → 당좌계좌 차·대변(강한 일관성) | `account`·`journal_log`·`transfer`(ACSP), `rtgs.result` 발행 | ACSP |
|
||||
| ⑤ | **Prada** | `rtgs.result` | 완결 규율(과반 확정) | `transfer`(ACCC)·`settlement_view`, (커밋 후) `rtgs.notify` 발행 | ACCC |
|
||||
| ⑥ | **Chanel**(결과통보) | `rtgs.notify` | 최종 pacs.002 생성, 접수센터만 송부 | `notification`(신청기관+수취기관) | — |
|
||||
|
||||
> **핵심 원칙**: 어느 센터로 접수돼도 **단일 순번기**가 하나의 전역순번으로 줄 세우고, 저널(단일 파티션)을
|
||||
> N센터가 **같은 순서로 결정론적 재생** → 세 센터 데이터가 항상 동일. 잔액 변경이 하나의 순번 줄로
|
||||
> 직렬화되므로 "동시에 같은 계좌"가 없어 **이중지급 원천 차단**.
|
||||
|
||||
---
|
||||
|
||||
## 2.5 서비스별 처리 개념도 (참조)
|
||||
|
||||
| 서비스 | 개념도 |
|
||||
|---|---|
|
||||
| Chanel(전문송수신) |  |
|
||||
| Dior(접수동기화) |  |
|
||||
| Hermes(결제/원장엔진) |  |
|
||||
| Prada(결과동기화) |  |
|
||||
|
||||
> 전체 업무 흐름은  참조.
|
||||
|
||||
---
|
||||
|
||||
## 3. 상태 전이도 (TxSts)
|
||||
|
||||
```
|
||||
(접수) (승인) (대기) (예약) (완결)
|
||||
RCVD ──▶ ACTC ──▶ [PDNG] ──▶ ACSP ──────────▶ ACCC
|
||||
│Chanel │Sequencer │Dior │Hermes(이체) │Prada(과반확정)
|
||||
│
|
||||
└─(검증실패/잔액부족/미등록기관)─▶ RJCT (반려)
|
||||
```
|
||||
- **RCVD** 접수 / **ACTC** 승인(순번부여) / **PDNG** 대기(원장 기록) / **ACSP** 예약(결제 반영, 결과대기) / **ACCC** 입금처리완료(최종) / **RJCT** 반려
|
||||
|
||||
---
|
||||
|
||||
## 4. 데이터 흐름
|
||||
|
||||
**Kafka 토픽** (전 센터 공유 단일 클러스터 = 순서 공유)
|
||||
- `rtgs.inbound` : Chanel → Sequencer (접수 원시)
|
||||
- `rtgs.journal` : Sequencer → 전 센터(Dior/Hermes) (전역순번 저널, **단일 파티션**)
|
||||
- `rtgs.result` : Hermes → Prada (결제결과)
|
||||
- `rtgs.notify` : Prada → Chanel (완결 결과통보 트리거; 접수센터가 신청/수취기관 앞 pacs.002 송부)
|
||||
|
||||
**PostgreSQL 테이블** (센터별 원장, 강한 일관성)
|
||||
- `account` 참가기관 당좌계좌 잔액 | `transfer` 거래 원장·상태 | `journal_log` 선저널
|
||||
- `settlement_view` 조회 사본 | `raw_message` 원전문(pacs.008) | `notification` 결과통보 아웃박스 | `app_user` 사용자·권한
|
||||
|
||||
**로그(ELK)**: 서비스 Logback(JSON, service/center 필드) → Logstash(:5000) → ES `rtgs-logs-*` → Kibana
|
||||
|
||||
---
|
||||
|
||||
## 5. 관리자(LouisVuitton) 워크플로우
|
||||
|
||||
```
|
||||
콘솔(:5174) "🛠 관리자" 탭 ──▶ louisvuitton(:8099) /admin/*
|
||||
· DB 초기화 : transfer/journal_log/settlement_view/raw_message TRUNCATE + 계좌 잔액 리셋
|
||||
· 코드 관리 : 참가기관(account) 마스터 CRUD + 상태코드 데이터사전
|
||||
· 사용자 권한 : app_user CRUD (ADMIN/ORG_S/ORG_R) — 로그인 강제는 후속
|
||||
· 대사 대시보드 : 상태별 건수·총액 보존 체크 + 서비스별 처리 현황(transfer/journal_log/settlement_view)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 개발 · 실행 워크플로우
|
||||
|
||||
**빌드** (JDK21로 — Gradle 8.10.2는 JDK26 미지원; `gradle.properties`에 고정)
|
||||
```
|
||||
cd C:\ai-dev\workspace\rtgs\backend
|
||||
gradlew build (EDR 파일락 시 재시도)
|
||||
```
|
||||
**기동/종료**
|
||||
```
|
||||
run-dc1.cmd : 네이티브 인프라(Postgres/Kafka) + 6개 서비스
|
||||
infra\start-elk-native.cmd : ES/Logstash/Kibana (로그)
|
||||
run-frontend.cmd : 콘솔(:5174)
|
||||
stop-dc1.cmd : 인프라 종료(데이터 보존)
|
||||
```
|
||||
**접속**: 콘솔 http://localhost:5174 · Kibana http://localhost:5601
|
||||
|
||||
**변경→반영**: 백엔드 = 재빌드(bootJar)+해당 서비스 재기동 / 프론트 = Vite HMR(자동)
|
||||
|
||||
---
|
||||
|
||||
## 6.5 Gucci(외부 경계 관문, :8095) 워크플로우
|
||||
|
||||
참가기관은 코어(Chanel:8091)에 직접 붙지 않고 **Gucci 관문**을 통한다(외부↔RTGS 북-남 경계).
|
||||
전역 결제순서는 **Sequencer 단독**이며 Gucci는 관문/인증/유량제어/전달보장만 담당(순서 결정 아님).
|
||||
|
||||
```
|
||||
참가기관 ──① 로그인(POST /gucci/auth/login, secret) ──▶ Gucci ── app_user.secret 대조 ──▶ JWT 발급
|
||||
──② 이체신청(POST /gucci/pay/customer, Bearer+X-Nonce+X-Timestamp) ──▶ Gucci 가드:
|
||||
[JWT검증] → [역할 ORG_S/ADMIN] → [유량제어 50/10s] → [재전송 nonce/timestamp]
|
||||
→ [기관바인딩: 토큰 org == 전문 DbtrAgt MmbId] → (통과) Chanel /pay/customer 프록시
|
||||
◀── pacs.002(RCVD) ──
|
||||
|
||||
[완결 후 결과 콜백송부 — G2]
|
||||
Prada 완결 → Chanel notification 아웃박스(delivered=false)
|
||||
→ Gucci DeliveryService(3s 폴링) → institution_endpoint 콜백 URL로 pacs.002 POST
|
||||
→ 2xx ACK: delivered=true / 실패: attempts++ 재시도(max 5)
|
||||
```
|
||||
- 감사로그(인증·허용/거부·송부)는 ELK(service=gucci)로 수집.
|
||||
- 헬스체크 `GET /gucci/health/centers`(관측). 다센터 정족수/펜싱·GSLB 라우팅은 G3(고사양 PC 이후).
|
||||
|
||||
---
|
||||
|
||||
## 7. 확장 워크플로우 (다센터 A-A-A, 향후)
|
||||
|
||||
```
|
||||
┌── DC1 (Chanel/Dior/Hermes/Prada + PostgreSQL rtgs_dc1)
|
||||
[단일 Sequencer] ──저널(Kafka 공유)──┼── DC2 (동일 서비스 + rtgs_dc2)
|
||||
└── DC3 (동일 서비스 + rtgs_dc3)
|
||||
· 컨슈머 그룹 센터별 분리(hermes-DC1/DC2/DC3) · 센터별 DB · 포트 오프셋
|
||||
· 정족수 2/3 자동전환 · 3센터 데이터 동일성 대사로 검증(개요 "3센터 동일순서 동일업무")
|
||||
```
|
||||
*필요 작업·자원은 개발일지 백로그 참조. 고사양 PC 이관 후 수월.*
|
||||
Reference in New Issue
Block a user