异步影响的业务问题线上排查

读前预知:

长方形代表第三方系统

圆形代表本系统

场景描述

  1. 用户通过第三方系统进行开户

  2. 第三方通知我方系统有用户开户, 这时会在我方系统 开户表 中存储一条用户数据,同时此刻用户已经可以进行订单充值了

  3. 用户正式使用我方设备时,通过我方验证,我方系统将会把用户数据由 开户表 中转移到 在线表

  4. 用户使用过程中,可以进行充值余额等操作,同时我方可以通知第三方的余额变化

  1. 用户有了充值订单以后,后续使用过程中,可以进行取消订单的操作,同时取消后也会通知第三方

  2. 注:取消订单的前提是,用户数据存在于我方系统中的开户表或者在线表

问题出现

某次测试同学使用时,发生用户存在于我方开户表中,但是取消充值订单时,第三方系统报错,告知我方该用户在第三方系统中没有查找到,关键这种情况还是时不时发生的。

按照上面的流程图,应该不会发生这种情况,最后查到的原因是,

有一种场景,第三方系统可以直接指定用户在某台设备中直接使用,而不是先开户,后面由用户自己登录使用第三方设备,

当直接使用这种场景时,根据我方系统的log日志观察,第三方会同时发送两次请求,

  1. 发送开户通知

  2. 发送使用请求

由于接口是同时请求的,因为网络各种原因,很有可能是使用通知先执行,这时候我方系统去删除开户表中的数据,虽然没有,但是不会影响后面的结果,如果没有则直接在在线表中插入一条用户数据,因为我们这里的强制需求是不能影响用户正常设备,所以即使开户表中没有数据,也要让用户正常使用,

当这种情况发生时,先执行了使用接口,后面又跟了一个开户接口,导致用户实际上已经进行使用了,但是后面又在开户表中添加了一条用户数据,

当用户注销使用的时候,我们只会删除在线表中的数据,没有删除开户表中的数据,导致后面取消订单的时候,通过了我方系统的验证,但是去通知第三方系统的时候,其实用户已经注销了,导致第三方无法找到该用户更新信息出错。

但是有的时候,又因为开户接口先请求到,使用接口后请求到,导致流程是顺畅的,所以没有这个问题,这种诡异的情况。

解决方案

  1. 使用接口使用Thread.sleep(1000)这种方式,这样让开户接口先执行,使用接口后执行,当然这个行不通,万一开户接口在1秒后才请求到呢?这个方式只是用于验证我的猜想做的。

  2. 兜底,当用户注销使用的时候,同时删除开户表在线表中的相关用户数据,这样取消订单时就不会发生乌龙了,这个是最终为了影响最小所接收和使用的方案。

  3. 跟第三方沟通指定设备使用时,两个接口合并为一个或串行请求,这个涉及到业务方的交涉,此处不讨论。

总结

这是对第三方的接口通知各方面以及设备使用没有作更完善的了解,导致的问题,因为不清楚直接指定设备使用,会同时请求两个接口,我方系统没做好异步的控制,后续与第三方系统对接时,尽量了解更多的场景,作更多的思考。

猜你喜欢

转载自blog.csdn.net/cainiao1412/article/details/109028626