一个工单引发的分布式系统调用的改造

        本文借用部门的小事改编的一博文。

1. 工单

      客服很着急的带着一袋子投诉工单找到我们研发部门:

      “你们怎么搞的,怎么这么退款不成功的?”

      其他的业务部门也纷纷来电致贺:‘’你们系统是不是挂了!”

2. 懵逼

      小编一下子就懵逼了,因为今天是小编值班,没有想到这么悲剧的事情发生了。小编的第一反应就是速度登录到后台,看看系统运行,没有问题。然后又迅速的电脑sgm监控系统,看看biz系统是不是稳定。

      不上不知道,以上吓一跳,tp99都是3000以上,我大叫一声不好,迅速在群里问谁在操作系统运营的升级、打包之类的。这时候小黄弱弱的说这个,现在正在让dba执行一个删除操作,是昨天基金公司收益推错了,现在删掉,重新推送收益。但是为什么一个删除操作就会出现这么大问题那?拿着菜刀找DBA去!

3. BDA解释

      DBA速度查看啦下监控,CPU间歇性打满。最终分析出来原来是分表分库操作中间件执行sql工具的问题。问题找到了,好吧,速度停掉,换种方式删除数据吧!

事情到这个时间的时候,应该是解决了,我舒舒服服的做到啦工位上。

4 事情远没有结束

      这个时候工单开始躲起来了,尤其是退款的的工单和冻结、解冻的工单,大部分工单都是支付系统成功,台账系统成功,账务系统调账成功,为什么我们系统显示的是处理中那?上下游系统都成功了,为啥你一个中游系统在处理中。下面开始通过系统和日志分析问题。

5.分析

      DBA执行数据库操作导致数据库的性能问题,这段时间的数据库的压力很大,一些插入和更新响应非常慢,导致平时不常见的并发更新问题,这个工单时消费退款的,具体体现为退款接口调用失败,原因是对应的原消费单状态是处理中,不是成功状态。在查询日志时发现了消费接口第一次调用时调账失败,异步重试的第二次调用是全部都处理成功,并且返回成功结果,订单此时不应该是处理中状态。

      下图是第一次调用,因为调账失败(调账失败也是因为并发导致,这里不分析),在18:40:41.461开始更新订单状态为处理中。



 

      下图是第二次调用,这次调账成功,在18:40:41.144开始更新订单状态为成功。

   
 
       根据两次更新时间可以看出,由于数据库插入和更新非常慢,导致接口调用超时,调用方异步发起的mq重试操作到更新时,时间比第一次请求的更新早了500ms,导致其更新成了成功状态后,又被第一次更新改回了处理中状态。

6. 处理

      针对这里更新并发问题,可以通过卡订单前置状态或乐观锁方式解决。本系统各类订单表都有version字段,需要各位在开发更新功能时,使用version字段实现乐观锁,如下图。


 

 7. 改造

      因为这个系统是我们半路接的系统,系统以前有些没有做完整的幂等性和并发性,下面我们要全面加上乐观锁,反之系统的请求的幂等性和数据的一致性出现错误。

8. 后记

      坑是无处不在的,但是天网也是恢恢的,群众看钱的眼睛是雪亮的,所以针对钱的系统你不要存在侥幸心理蒙混过关,到时候发现了,你会很尴尬的。

 

猜你喜欢

转载自aa8945163.iteye.com/blog/2356279