問題描述
第三方的用戶A用戶定了5筆訂單,B用戶定了1筆訂單。但是訂單中心收到的卻是A定了4筆訂單,B用戶定了2筆訂單。
初步排查
整個調用流程為
上游渠道->sdp->訂單中心(本系統)->下游渠道
初步懷疑是sdp進行轉發的時候導致了并發問題。所以就將sdp的日志進行查看排查,結果發現sdp的轉發沒有問題,所以開始進行訂單中心的代碼審查。
訂單中心排查
因為是訂單中心代碼日志打印的時候,已經出現了入參替換,所以懷疑是在日志攔截器之前。剛好,在日志攔截之前有一個對request進行替換的動作發生了。所以查找這個類ChangeInVarsFilter。看到了他具體的替換邏輯如下圖:
替換request代碼實現
那么再次進入這個方法看到如下邏輯:
具體的獲取Wrequest邏輯
看到這里,就發現了一個變量resourceStr,只有這個變量可能出問題了,因為其他的都是線程安全的。都是方法內變量。所以繼續查看。
resourceStr的變量類型及初始化時機
看到這里,基本上也明白是咋么回事了。也就是resourceStr變量是一個靜態變量,是共享資源。當線程a完成了對resourceStr的初始化的時候,還沒有來得及做下面的動作,b線程進入,并且又對resourceStr進行了初始化。再接下來的動作中a線程中的變量resourceStr已經與b線程的一致。
至此,問題基本明了,接下來就是修改了。
問題解決
問題解決思路,將共享變量resourceStr變成對象的成員變量,如下圖:
resourceStr實例變量
然后就方法也改為實例方法即可。改造完成。試了下效果沒有問題。