中文 EN

系统设计 Lab

Payment ledger 的瓶颈是 correctness,不是 QPS:钱绝不能被凭空造出、丢失或被 double-charge。

调节支付速率、idempotency-key TTL、外部 provider 的 latency、ledger entry 总数、reconciliation 窗口和 region 数。设计会先加上保证 correctness 的机制——idempotency key、append-only 的 double-entry ledger、ACID 写入、异步的 PSP state machine——只有在 integrity 锁定之后,才按 account 分区。

分步讲解

一步一步把它想清楚

常规演进场景

从左到右点击,就是预设的演示路径。每张卡片都会改变 workload 输入。

Workload

这些是输入,不是预设好的架构阶段。

推荐形态

当前架构路径
Payment ledger 架构图 payment + ledger 系统的白板风格架构图:clients、带 idempotency layer 的 payment API、double-entry 的 ledger service、带 account 分区的 ACID datastore,以及由 PSP adapter、reconciliation 和 audit log 组成的异步层。 Clients Payment API Ledger Datastore Async + audit Client 提交 + 重试 Payment API 请求处理 Idempotency layer 去重重试 Ledger service double-entry ACID store transactional Account shards 按 account 分区 PSP adapter 异步 capture Reconciliation 对账匹配 Audit log 事件 trail
Clients
Client 提交支付,超时就重试,有时会重发同一个请求
Payment API
Payment API 校验支付请求,并掌管支付的 state machine
Idempotency layer 存下 idempotency key,让重试请求只被处理 exactly once
Ledger
Ledger service 把配平的 debit 和 credit 记录为不可变的 source of truth
Datastore
ACID store 原子且持久地提交配平的 entry
Account shards 把 ledger 按 account 分区,让写入扩展又不破坏配平
Async + audit
PSP adapter 通过又慢的外部 provider 做 authorize 和 capture,配合重试和 DLQ
Reconciliation 重新拉取 provider 记录,并和 ledger 重新配平
Audit log 为合规保留一条 append-only 的事件 trail,记录每一次状态转换

瓶颈

Ledger 写入负载

Idempotency-store 负载

PSP 相关的异步 backlog

Ledger 存储增长

Reconciliation 延迟

为什么会变

    决策权衡

    Idempotency layer

    Double-entry ledger

    Transaction 模型

    PSP 集成

    Reconciliation

    Audit / event log

    有出处支撑的规则

    这些是模型背后那些经得起时间考验的 system design 论断。而 slider 的具体阈值,则被刻意标注为教学用的假设。

    已验证的规则

    Idempotency key 让重试的支付请求可以安全重放

    Stripe 让 client 在请求上带一个 idempotency key,于是网络故障引发的重试会返回原始结果,而不是再创建一次 charge。

    Stripe Docs
    已验证的规则

    异步地 capture 资金,因为 provider 又慢又可能失败

    一个 PaymentIntent 会经过 requires_action、processing 和 succeeded 状态;把 capture 当成异步的 state machine,就能容忍 provider 的 latency 和失败。

    Stripe Docs
    已验证的规则

    append-only 的 double-entry ledger 是不可变的 source of truth

    把钱建模成往 account 上配平记账,让 ledger 可审计、能自校验,于是余额是推算出来的,而不是就地改动的。

    martinfowler.com
    已验证的规则

    Event sourcing 保留一条完整、可重放的状态变更审计 trail

    把每一次状态转换都持久化成一个不可变事件,就得到了一份完整的审计 log,还能通过重放历史来重建余额。

    martinfowler.com

    教学用假设

    • Correctness 才是瓶颈;单节点的吞吐和存储预算是保守的教学数字,不是厂商上限。
    • 每笔支付都按一次配平的 double-entry 写入建模;idempotency store 大约每次尝试(含重试)看到一次查找。
    • PSP 相关的 backlog 按「支付速率 × provider latency」估算,也就是在等外部 provider 的 in-flight capture 数。