Files
rtgs/docs/RTGS 프로토타입 워크플로우.md
rtgs 58ca23b5d9 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 보고서/복원력방안)
2026-07-15 15:37:32 +09:00

11 KiB

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(전문송수신) Chanel
Dior(접수동기화) Dior
Hermes(결제/원장엔진) Hermes
Prada(결과동기화) 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 이관 후 수월.