2019-01-02线上问题排查

问题描述

第三方的用户A用户定了5笔订单,B用户定了1笔订单。但是订单中心收到的却是A定了4笔订单,B用户定了2笔订单。

初步排查

整个调用流程为
上游渠道->sdp->订单中心(本系统)->下游渠道
初步怀疑是sdp进行转发的时候导致了并发问题。所以就将sdp的日志进行查看排查,结果发现sdp的转发没有问题,所以开始进行订单中心的代码审查。

订单中心排查

因为是订单中心代码日志打印的时候,已经出现了入参替换,所以怀疑是在日志拦截器之前。刚好,在日志拦截之前有一个对request进行替换的动作发生了。所以查找这个类ChangeInVarsFilter。看到了他具体的替换逻辑如下图:


2019-01-02线上问题排查_第1张图片
替换request代码实现

那么再次进入这个方法看到如下逻辑:


2019-01-02线上问题排查_第2张图片
具体的获取Wrequest逻辑

看到这里,就发现了一个变量resourceStr,只有这个变量可能出问题了,因为其他的都是线程安全的。都是方法内变量。所以继续查看。
2019-01-02线上问题排查_第3张图片
resourceStr的变量类型及初始化时机

看到这里,基本上也明白是咋么回事了。也就是resourceStr变量是一个静态变量,是共享资源。当线程a完成了对resourceStr的初始化的时候,还没有来得及做下面的动作,b线程进入,并且又对resourceStr进行了初始化。再接下来的动作中a线程中的变量resourceStr已经与b线程的一致。
至此,问题基本明了,接下来就是修改了。

问题解决

问题解决思路,将共享变量resourceStr变成对象的成员变量,如下图:


2019-01-02线上问题排查_第4张图片
resourceStr实例变量

然后就方法也改为实例方法即可。改造完成。试了下效果没有问题。

你可能感兴趣的:(2019-01-02线上问题排查)