专业书籍精读 · System Design Interview 卷二 · 第 11 章

设计支付系统

System Design Interview Vol 2 · Ch 11 · Alex Xu & Sahn Lam · 2022

EN →

这一章讲什么?

你在购物 App 上点「立即付款」,一秒后页面说「支付成功」。这一章造的就是那一秒里跑完的东西:把钱从买家那边收进来,再在某一天把钱结给卖家,而且一分不能多、一分不能少。

先说个怪事

这套系统慢得出奇。一天一百万笔交易,摊到每秒只有十来笔——比一个中型论坛的刷新还少。可它偏偏是整本书里最难写对的一章。

因为难点根本不在快,在于「钱到底动没动」这句话必须有确定答案。

旧世界为什么难

你按下付款键,手机转了三十秒,跳出一行「网络错误」。钱扣了吗?你不知道,你的服务器也不知道。请求可能压根没送到,也可能银行早扣了、只是回执丢在路上。

这时系统只有两条路:当它没成功——用户可能白白被扣一笔;当它成功了——商家可能白发一件货。更糟的是用户自己会再按一次,于是一次购物扣两回钱。

核心机制直觉

① 给每次付款发一张号码牌。同一张号码牌无论递上来几次,窗口只办一次事,第二次直接把第一次的收据再抄一份给你。于是「不确定成没成,就再试一次」从危险动作变成安全动作。

② 记账要一笔记两边。每一分钱的移动都同时落在两个账户上,一边减一边加,全部加起来永远是零。漏记一笔,一求和就露馅——钱守恒不是靠会计细心,是靠记账格式本身。

③ 每天晚上对一次账。你自己记的流水,和支付公司发来的流水,逐笔比。对得上的过,对不上的挑出来:差个手续费这种能自动补,剩下说不清的交给人工。这一步不是保险,是必需品——前两招永远盖不住全部情况。

④ 卡号根本不进你家。刷卡那一页是支付公司的,卡号直接进他们的机器,你只拿到一串替代号码。你存不了的东西,就泄露不了。

代价在哪

这一整套把「付款」从一个动作变成了一条带状态的流程:它会卡在「处理中」、会进重试队列、每天还留下一小撮必须人工处理的尾巴——这些麻烦就是买「正确」花的钱。

一句话记住

支付系统慢得离谱却难得离谱,因为它唯一的任务是让「钱动没动」有确定答案。网络超时时你分不清成功与失败,所以每笔付款带一张只认一次的号码牌,让重试重新变安全;账目一笔记两边,让漏账藏不住;每天再和支付公司的流水对一遍,把前两招漏掉的挑出来人工修。至于卡号,压根不让它进你的机器。

想进到具体机制、记号和示意图? → 切到精读版