4. 对账平台总体架构设计
对账平台不是“把两边账单拉出来比一比”的脚本集合,而是一套需要长期稳定运行、每天处理千万级流水、并且要对差错结果负责的生产系统。它的总体架构必须同时回答四个问题:系统分成哪几层、每层承担什么职责;模块如何切分才能既解耦又不丢一致性;数据从支付渠道到差错结论要经过哪些加工环节;以及在渠道超时、文件延迟、节点故障时如何保证对账结果不缺失、不重复、可追溯。本节围绕这四点展开,并给出可直接用于工程落地的分层方案与选型依据。
一、分层架构:把“接入差异”和“对账逻辑”隔离开
推荐采用五层架构,自上而下为:接入层、标准化层、对账核心层、差错处置层、数据服务层。分层的核心目的,是把“每个渠道各不相同的报文格式、文件命名、拉取方式”收敛在接入层和标准化层,让对账核心层只面对统一的内部模型,从而避免每接入一个新渠道就改动对账算法。
接入层负责与外部渠道交互,包括主动拉取(如微信、支付宝的账单文件下载接口)、被动接收(渠道推送的对账文件到 SFTP/OSS)、以及查询补偿(对账不平后调用渠道单笔查询接口)。这一层要处理鉴权、限流、重试、断点续传和文件完整性校验(如 MD5、文件记录数比对)。
标准化层把渠道原始数据转换为平台统一模型。统一模型的关键字段建议固定为:channel_code(渠道编码)、channel_trade_no(渠道流水号)、merchant_order_no(商户订单号)、trade_amount(交易金额,单位分)、fee_amount(手续费,单位分)、trade_status(渠道状态)、trade_time(渠道交易时间)、settle_date(清算日期)。金额统一用“分”存储为整数,避免浮点误差;时间统一转为 UTC+8 并保留原始时区标记,防止跨日对账错位。
对账核心层是平台的心脏,包含匹配引擎、规则引擎和差异判定。匹配引擎按“主键匹配 + 辅助匹配”两级策略工作:先用 channel_trade_no 或 merchant_order_no 做精确匹配;对匹配不上的记录,再用“金额 + 时间窗口(±5 分钟)+ 渠道”做模糊匹配,用于识别渠道流水号变更或商户单号回填延迟的情况。
差错处置层把差异分为四类:平台有渠道无(长款)、渠道有平台无(短款)、金额不一致、状态不一致。每类差异生成差错工单,支持自动重查、人工复核、挂账和核销。
数据服务层提供对账结果查询、报表导出、对账明细追溯和开放 API,供财务、运营和风控系统消费。
二、模块划分:按“变化频率”切分,而不是按“功能名称”切分
模块划分最容易犯的错误是按“对账、差错、报表”这种功能名切分,结果每个模块都要处理所有渠道的差异。更合理的做法是按变化频率切分:渠道接入适配器是高频变化的(每接一个渠道就要改),对账匹配引擎是低频变化的(算法稳定),差错处置流程是中频变化的(业务规则调整)。因此建议划分为六个核心模块:
- 渠道适配模块:每个渠道一个适配器实现,统一实现
fetchBill()、parseBill()、queryTrade()三个接口,新增渠道只增加实现类,不改核心。 - 账单管理模块:负责账单文件的登记、状态跟踪(已下载/已解析/已对账/已归档)和重跑控制。
- 匹配引擎模块:无状态计算模块,输入两方标准化流水,输出匹配结果和差异集合,便于水平扩展。
- 规则配置模块:按渠道维度配置容差金额、忽略状态、时间窗口等参数,支持热更新。
- 差错工单模块:差异落库、工单流转、重查任务调度。
- 调度与监控模块:控制对账任务触发时机(如 T+1 凌晨 2:00),监控账单到达率、对账成功率、差异率。
三、数据流:从渠道文件到差错结论的完整链路
以某渠道 T 日对账为例,数据流如下:T+1 凌晨 1:30 渠道账单文件到达 OSS,接入层在 2:00 触发拉取任务,校验文件 MD5 与记录数后写入原始表 ods_channel_bill_raw;标准化层在 2:15 完成解析,写入 dwd_channel_trade,同时平台侧从交易库抽取 T 日流水写入 dwd_platform_trade;2:30 匹配引擎启动,按 channel_trade_no 精确匹配,未命中记录进入模糊匹配;3:00 输出匹配结果表 dws_recon_result,差异记录写入 dws_recon_diff;3:10 差错工单模块生成工单并触发自动重查;财务在 9:00 上班后处理剩余人工工单。整条链路的关键是每个环节都有批次号 batch_no 贯穿,任何一条差异都能反查到原始文件和原始流水。
四、技术选型:按数据量和实时性要求分层选择
| 层次/模块 | 推荐技术 | 选型理由 |
|---|---|---|
| 接入层调度 | XXL-JOB / DolphinScheduler | 支持分片、失败重试、任务依赖,适合账单拉取这类定时批任务 |
| 原始文件存储 | OSS / MinIO | 账单文件体积大、需长期归档,对象存储成本低且支持生命周期管理 |
| 标准化与匹配计算 | Spark / Flink(批) | 单日流水可达千万级,需分布式计算;Flink 可用于准实时对账场景 |
| 结果存储 | MySQL(分库分表)+ ClickHouse | MySQL 存工单和状态,ClickHouse 存明细供快速查询和报表 |
| 规则配置 | Apollo / Nacos | 规则需热更新,避免每次调整都发版 |
| 监控告警 | Prometheus + Grafana + 钉钉/企微 | 监控账单到达率、对账耗时、差异率,异常及时通知 |
五、高可用设计原则:对账结果“不丢、不重、可重跑”
对账系统的高可用不等于“服务不宕机”,而是“结果正确且可恢复”。三条原则必须落实:
第一,幂等与批次隔离。每次对账以 batch_no 为隔离单位,同一批次重复执行时先删除该批次结果再重算,或使用唯一键 (batch_no, channel_trade_no) 做 upsert,保证重跑不产生重复差异。
第二,断点续传与状态机。账单文件下载和解析都要记录状态,失败后从断点继续,而不是整批重来。状态机建议为:INIT → DOWNLOADED → PARSED → RECONCILED → ARCHIVED,任何一步失败都可从该步重试。
第三,差异可追溯与人工兜底。每条差异必须保留原始渠道记录和平台记录的快照,即使后续数据被修正,也能还原当时的对账依据。同时保留人工调整入口,用于处理渠道侧确认无法修正的历史差异。
综上,对账平台的架构设计应以“接入差异收敛、核心逻辑稳定、数据链路可追溯、故障可重跑”为四条主线。分层是为了隔离变化,模块划分是为了控制影响面,数据流设计是为了保证可追溯,技术选型和高可用原则则是为了让这套系统在真实生产环境中持续可信地运行。