连载中 16/18

对账系统:最终一致的最后防线

2026-06-22 · 6549 阅读 · 0 评论 · 0 赞

防御全做了,差异还是来了

消息表、事务消息、幂等、对账……不对,对账还没做。老王的系统上线半年,防御工事全齐,季度审计却翻出两笔三个月前的差异:一笔支付成功但订单状态停在待支付,一笔退款重复。根因分别是「MQ 集群主备切换丢了一条消息」和「一个从未想到的故障组合」。这两笔教了他最后一课:防御是概率游戏,对账是确定性游戏——无论防御多密,都要假设差异会发生,并有一套独立机制把它们找出来。

对账的本质:不信任自报

对账的核心思想一句话:不拿任何一方的内部状态当真理,用两份独立产生的数据互相印证。我方订单表对渠道方账单文件,渠道账单对银行流水,银行流水对账务总账——链条上每一环都拿「对方独立记录的数据」比「我方记录的数据」。差异必然藏不住:两边数据来源不同、生成路径不同,想两边同时错得互相一致,概率趋近于零。

两级对账:快扫与全量

准实时对账(分钟级):订单落库后几分钟内,把流水发到比对队列与下游回执比对,差异快速浮出。灵敏但可能有盲区(队列丢、延迟乱序),当哨兵用。

日终对账(T+1):金融行业标配。次日拿到对方的账单文件(渠道账单、银行流水),与本系统前一天的流水全量逐笔比对。慢一拍,但全量、确定性、无盲区,是真正的兜底。两级配合:准实时负责「尽快发现」,日终负责「一个不漏」。

对账四步与三种差异

取数:我方流水 + 对方账单(文件/接口)
清洗:统一格式、统一对账键(流水号)、金额规整
比对:按对账键 join,逐笔核对金额与状态
分流:差异进差错处理流程

比对结果分三类,行业黑话要记牢:长款——对方有、我方无(渠道扣了钱,我方没这笔单,多为通知丢失);短款——我方有、对方无(我方记了成功,渠道没扣到,最危险,涉及多发货物或服务);状态/金额不符——两边都有但对不上(金额不一致、我方成功对方失败)。三类差异的处理策略完全不同,不能一锅烩。

差错处理三路分流

处理路径条件例子
自动平账规则明确、风险可控长款补单落库、漏发消息补发
人工差错池可疑、涉及资金决策金额不符、疑似重复支付
挂账短期无法定论进过渡科目,定期清理

分流的红线:自动平账只做「低风险可逆」的动作——补落库、补发消息可以,自动退款、自动扣款不行,钱上的决定必须人工。挂账不是垃圾桶,要有清理 SLA(比如 30 天),挂久了就是审计问题。

系统设计的四个细节

一:对账键要稳——双方约定的唯一流水号,跨系统唯一且永不复用,这是对账的命根子。二:支持重跑——对账任务本身也会挂,同一批数据重跑结果必须一致(对账逻辑做成幂等)。三:容错窗口——对方数据晚到是常态,比对要有时间窗(比如 T+1 比对时容忍 T-1 的尾巴),窗口参数进配置。四:差错率指标化——每日差异笔数 / 总笔数是系统健康度的体温计,趋势恶化比单笔差异更值得警觉。

小结

对账一句话:独立数据源全量比对,准实时当哨兵、日终当兜底;长款短款分流处理,自动只做可逆动作,挂账要有清理期限;差错率是体温计。至此防御与兜底齐活。老王半年攒下的教训远不止这些——那些方案救不了、只能靠纪律防的坑,下一篇集中曝光:踩坑实录。

503

10 年全栈工程师 · 503咖啡馆主理人

#分布式事务#对账#长款#短款#差错处理

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 4 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞