结算场景下的跳坑记

用户头像
墨凡
关注
发布于: 2020 年 08 月 16 日
结算场景下的跳坑记
前言

本文要说明的是结算服务调用时的错误设计,关于结算系统的细节,没有相关经验,不做描述。此处将结算系统看做一个服务接收方。

结算服务描述:
  1. 接收参数包括:结算单号、请求UUID、业务参数、扩展参数。

  2. 支持首次下发、失败二次拉起。(区别在于:应对银行系统的失败情况,不必再走结算审核流程)

  3. 结算系统根据结算单号,或者请求UUID做幂等性处理。

  4. UUID说明:这个跟单号的区别在于,是标记结算单一次操作的唯一码,可以是系统编码+业务编码+结算单号+状态,那么在结算单的每个状态下的操作都对应一个操作码

调用方:
  1. 结算单号生成,请求UUID生成,参数封装。

  2. 失败情况二次发起。

错误的调用设计:
  1. 结算单号,在下发结算时生成。

故障过程:

当结算发起方在调用结算服务时,生成固定格式的唯一单号,这里采用"业务主键-伪随机数"作为结算单号。系统稳定时,一切正常。但是出现异常时,将存在相同数据,不同结算单号的多条记录情况。

比如:在结算服务超时情况下的调用,此时有两种可能:一种是结算超时,结算系统失败。另一种,结算超时,但是结算单在结算系统正常保存了。此时,调用系统发现超时异常,回滚单据状态至待发起结算。用户又操作点击发起,就会导致两条相同金额不同结算单号记录。

故障改进:
  1. 在业务主数据生成时预生成结算单。发起结算时,始终使用预生成的单号,当该结算单生命周期结束时,预生成一条新的结算单号。这样即可利用结算服务的幂等设计防止重复数据的发生。

故障后的思考:
  1. 研发人员的程序编码阶段对异常情况考虑的覆盖不全。

  2. 测试阶段未覆盖多次发起的场景。假定服务、网络是稳定的。

后续发展:
  1. 业务要求在上游审批环节结束后,自动发起结算。考虑失败情况,需要增加重试机制,有了前边的故障改进,才使这种错误免于大面积发生,倘若结算单号不是预先生成,若干次的重试,将会是可怕的后果。

  2. 单据在状态流转过程中,还需要考虑状态迁移的限制特性,借鉴状态机理论,增加前置状态校验。目标状态迁移的幂等设计。

发布于: 2020 年 08 月 16 日 阅读数: 45
用户头像

墨凡

关注

文字,是一种表达方式 2017.12.22 加入

90后程序员,对代码有追求,对人生有态度

评论

发布
暂无评论
结算场景下的跳坑记