Part 10 · System Design · 10.1.11

Thiết kế hệ thống ngân hàng bằng Java microservices trên AWS

Bám theo bài toán chuyển tiền đã học ở Java concurrency, nhưng mở rộng từ một process thành hệ thống production: ledger đúng, API retry-safe, workflow phục hồi được và Auto Scaling không phá capacity của database.

1. Scope và invariant trước công nghệ

Critical journey: xem số dư, chuyển tiền nội bộ và tra trạng thái giao dịch. Invariant quan trọng nhất là tiền không tự sinh/mất; một transfer chỉ được post một lần; ledger đã post là immutable và mọi correction tạo entry mới. Tách available balance , book balance và trạng thái PENDING/POSTED/FAILED/REVERSED/MANUAL_REVIEW .

Liên hệ: lab Java dùng lock ordering để bảo vệ hai Account trong một JVM. Khi đã thành distributed system, JVM lock không còn đủ; invariant phải nằm trong database transaction/ledger ownership và protocol idempotent.

2. Boundary đề xuất

Component Ownership Ghi chú
Transfer Service Transfer intent, state machine, idempotency Orchestrate workflow; không tự sửa ledger của service khác.
Ledger Service Accounts, immutable debit/credit entries, balance projection Strong invariant; double-entry trong một local transaction.
Risk/Limits Velocity, daily limit, fraud decision Đồng bộ nếu quyết định bắt buộc trước post; optional signal có thể async.
Notification Email/SMS/push delivery Async, không nằm trên critical correctness path.
Audit/Reconciliation Evidence và mismatch repair workflow Không thay source-of-truth ledger.

Ban đầu có thể triển khai Transfer + Ledger trong modular monolith để giữ transaction đơn giản. Chỉ tách khi ownership, scale hoặc release cadence thực sự khác; không tạo microservice theo từng table.

3. API retry-safe

POST /transfers
Idempotency-Key: 2e9...
{
  "fromAccountId": "A1",
  "toAccountId": "A2",
  "amount": 100000,
  "currency": "VND"
}

Lưu key + request fingerprint + trạng thái/kết quả trong cùng transaction với transfer intent. Cùng key/cùng payload trả outcome cũ; cùng key/khác payload trả conflict. Client timeout không được suy ra thất bại: query GET /transfers/{id} . Authentication không thay object-level authorization; account phải thuộc principal và policy cho phép operation.

4. Ledger và concurrency

Post debit và credit bằng double-entry trong cùng local ACID transaction; tổng entry theo transaction bằng zero. Dùng row lock theo thứ tự ổn định hoặc optimistic version + bounded retry tùy contention. Unique constraint trên business transaction/idempotency key là hàng rào cuối chống double posting. Không dùng floating point cho tiền; lưu minor unit integer hoặc decimal với currency/scale rõ.

Red flag: đọc balance → kiểm tra → update bằng hai request/transaction rời; hoặc tin rằng synchronized / AtomicLong bảo vệ được nhiều instance.

5. Distributed workflow

  1. Nhận request, validate và persist transfer intent/idempotency.
  2. Risk/limit decision có deadline và result audit.
  3. Gửi command post ledger qua local call hoặc durable message.
  4. Ledger post debit/credit atomically và ghi Outbox.
  5. Consumer cập nhật transfer state idempotently; notification chạy async.
  6. Reconciliation tìm transfer stuck, duplicate/missing effect và đưa case bất định sang manual review.

Outbox đóng atomicity gap DB + broker nhưng không tạo exactly-once end-to-end. Consumer cần Inbox/unique event ID; retries có backoff, jitter, DLQ và owner. Reversal là business transaction mới, không xóa/sửa lịch sử ledger.

6. Reference architecture trên AWS

Route 53 -> CloudFront/WAF -> ALB/API Gateway
                              |
                    Java Transfer/Ledger services
                    ECS/Fargate | EKS | EC2 ASG
                       |         |        |
                  Aurora/RDS  ElastiCache  SQS/MSK
                       |                    |
                  PITR/backups       async consumers

CloudWatch + OpenTelemetry | Secrets Manager/KMS | IAM roles

Compute chạy ít nhất hai AZ; data store chọn Multi-AZ theo RTO/RPO. Private subnet cho application/data, IAM role ngắn hạn, encryption in transit/at rest và audit log không chứa credential/PII nhạy cảm. Multi-Region chỉ khi requirement biện minh consistency, failover và operational cost.

7. Auto Scaling đúng cách

Workload Signal tốt Guardrail
Transfer HTTP Request count/target, concurrency, p95 latency Min/max, warmup, scale-in stabilization, ALB drain.
SQS consumer Backlog age và messages/worker Visibility timeout, idempotency, downstream capacity.
EKS pods HPA theo CPU/concurrency/custom metric Requests/limits đúng; node autoscaler phải kịp cấp capacity.
EC2/ECS Target tracking hoặc step scaling Multi-AZ, health grace period, lifecycle hooks.

CPU không phải metric mặc định cho mọi service. Auto Scaling có detection + provisioning + JVM/Spring warmup lag; flash burst cần headroom, scheduled scaling hoặc queue. Scale-out caller không làm RDS mạnh hơn và có thể gây connection storm.

8. Capacity contract cho Java/JVM

9. Availability, security và operations

Định nghĩa SLI theo tỷ lệ transfer đạt terminal outcome đúng trong latency mục tiêu, không chỉ HTTP 200. Alarm error rate, p95/p99, stuck-transfer age, reconciliation mismatch, queue age, pool wait, DB saturation và Auto Scaling không đạt desired capacity. Deployment canary/blue-green phải hỗ trợ mixed versions và expand-migrate-contract. Dùng least privilege, maker-checker cho operation nhạy cảm, immutable audit, rate/amount limits và tested break-glass procedure.

10. Failure matrix cần nói trong interview

11. Design review checklist

EC2 Auto Scaling · ECS Service Auto Scaling · EKS Autoscaling · AWS Financial Services Lens