背景
今天给大家分享一个话题,就是对于线上跟钱有关的计费类的系统,在线上可能出现的一些把钱算错的问题,以及我们如何来设计架构解决这些问题。
但凡是跟算钱相关的系统,都是每个公司的重中之重,比如说价格系统、运费系统、计费系统、支付系统、基金系统、财务系统、结算系统等等,因为这些系统运行过程中,随时可能因为技术问题或者运营的人为误操作问题,把钱给算错了。
所以今天来给大家讲讲这一类跟算钱有关的系统,我们应该如何来保证他不会把钱给算错呢?
计费业务系统架构设计
业务场景引入
首先,我们先来引入一个业务场景,假设我们现在有 B 端、M 端和 C 端三个系统。
其中 B 端可以由商家/入驻客户/供应商/合作伙伴这一类 B 端角色对自己的一些计费规则进行设置和调整,M 端是是公司的运营可以进行统一的基础性计费规则调整,C 端是面向用户的,在处理一些请求的时候,会根据 B 端和 M 端的计费规则进行计算,算出当前的支付金额。
如下图:
这个时候可能你说了,这看起来没啥问题啊,不就在平台层和商家层允许修改计费规则,然后c端系统实时根据两个系统的计费规则计算费用么。
真的是这样吗?上面那套计费模型里,看着简单,其实蕴藏着大量的问题,下面来给大家一一说明。
业务系统消息同步丢失
首先,因为历史原因,上述计费模型会非常的复杂,不是我们看起来那么的简单。
实际上,B 端系统每次修改完了计费规则以后,是要把计费规则通过 MQ 同步给 M 端系统的,然后 M 端系统会汇总 B 端系统的所有商家的计费规则,接着后续 C 端系统在计费的时候,是调用 M 端系统的接口拉取所有需要的计费规则来进行计算的。
如下图所示:
单单就上图这一个架构,就可能会让我们在计费的时候可能因为一些技术原因出现问题。
比如说最典型的就是,不管因为什么,B 端系统那里修改了计费规则以后,可能因为网络原因、MQ 故障、代码 bug 等各种原因,并没有同步到 M 端系统那里去,这就会导致 C 端系统一直用老的计费规则在计费。
严格来说,这就已经导致计费错误了,如下图所示:
这还仅仅只是同步问题导致的计费错误而已,其实还有更加麻烦的一个问题,那就是当 M 端系统收到了 B 端系统同步过来的计费规则了以后,他可能会陆续把复杂的计费规则写入多个数据存储中。
没错,你没看错,有可能 M 端系统会用异构数据存储架构,来存放不同的计费规则,比如 MySQL、MongoDB,等等。
如下图:
| 计费业务系统计费问题
这个时候可能会出现一个问题,那就是 C 端系统可能会在你的一次计费规则同步的过程中,就从你 M 端系统这里来查询各种计费规则来进行计费。
但是这个时候有可能会出现一个问题,那就是 MongoDB 里可能已经是最新的计费规则,而从 MySQL 里查出来的还是老的计费规则,也就是说,完全可能会出现,用了不一致的计费规则来进行计费。
比如下图:
这是第二个可能出现计费错误的场景,第一个计费规则同步失败和第二个计费规则并发读写,都是技术类的问题。
第三个计费错误的场景,就是我们的商家或者自己的运营,手欠甚至手抽,把计费规则改成了非常离谱的错误。
比如说,某一个计费规则正常基准金额是百元级别的,但是他给改成了几块钱,这可能会导致公司出现严重的损失。
如下图:
所有这一切问题,都可能会导致计费的错误,那么说到这里,大家是不是想说,那还不简单,case by case 的优化和处理不就完了。
比如说对 B 端和 M 端系统进行大范围的加固,实现 MQ 消息不丢失保障机制,对 M 端系统异构存储写入和读取,加个分布式锁,写入的时候不能读取,读取的时候不能写入,对运营修改计费规则的时候进行校验,加入各种校验规则,乱改就不让你通过。
没错,大家说的这些其实都可以,但是不知道大家想过一个问题没有,对于真正复杂的公司级系统,比如上述的 B 端系统,看起来在图里仅仅是一个框而已。
其实一家公司里可能是几十个人维护的大平台,M 端系统也是同理,所以如果要推动各方实现各种技术方案来做保障,首先在跨部门推动方面成本就是很高的。
这仅仅是其一,其二,就是你现在做了一些措施做了加强,但是不代表以后就不会有新的问题了。
比如说,你对 MQ 同步实现了消息不丢失方案,可是哪一天如果 MQ 挂了呢?
比如说,你如果在 M 端系统实现写入和读取加分布式锁做互斥,那可能会导致并发性能大幅度的降低。
比如说,你给计费规则修改加入校验规则,可是随着计费规则不停的变化,很可能会导致你的校验规则失效,或者要持续不断的加入更多新的校验规则。
如下图:
计费业务数据补偿系统设计
所有这一切其实都是治标不治本,对于这一类线上跟钱相关的,固然应该在技术和业务上严防死守,但是这都依赖技术团队的技术素养,以及对业务校验规则的持续维护,如果想要一劳永逸,那么通常我们会引入一套计费数据补偿系统。
这个计费数据补偿系统,是额外独立开发的,我们来看看,用这个系统我们会实现哪些功能来解决刚才看到的那些问题。
首先,从本质上来说,我们不管具体的 B 端和 M 端的代码逻辑是如何写的,第一个有一点是可以肯定的,那就是 B 端和 M 端是需要实现数据同步和最终一致的。
所以说,我们不管他们之间是通过 MQ 来同步或者是什么,我们可以直接监听 B 端和 M 端系统的数据存储,通过定时拉取数据来实现比对,如果一旦发现两边数据不一致,则自动实现补偿。
如下图:
接着我们再来看第二个问题,不管你的 M 端计费规则的写入和查询逻辑如何,最大的问题就是你的某一次计费结果可能并没有按照一致和正确的计费规则来进行。
所以说,我们的计费数据补偿系统可以直接让 C 端系统的计费接口把每次计费请求的日志上报给我们。
接着我们可以同时把 M 端系统的每一次计费规则的查询和修改日志也上报给我们,我们可以把相关日志数据存储到大数据系统中。
接着我们就可以基于大数据技术来进行相关系统的日志运算,检查一下每一次计费运算查询多个规则的时候,是否出现了多个规则在短时间内先后修改,然后导致使用了不一致的规则来计算的问题。
如下图所示:
最后就是对于运营可能误操作改错计费规则的问题,我们可以拉取 C 端系统的每一次计费结果,然后对计费结果我们可以进行环比比对校验。
就是说,你每一次计费结果都可以更过去的类似的计费结果进行比对,如果说差距过大,超过了 50% 的话,那么就会自动发送告警给运营,提醒他可能出现了计费额规则误操作的问题。
如下图所示:
总结
通过上述的计费数据补偿系统,就可以直接绕开所有的具体计费规则和计费逻辑,跟 C 端系统、B 端系统、M 端系统完全解耦。
采用自行拉取数据、拉取日志、拉取计费结果等手段,用大数据一类的技术进行各种检测,从根本上解决问题,以此来实现线上计费系统因为技术问题或者误操作问题导致的计费错误。
-