非同步影響的業務問題線上排查
讀前預知:
長方形代表第三方系統
圓形代表本系統
場景描述
-
使用者通過第三方系統進行開戶
-
第三方通知我方系統有使用者開戶, 這時會在我方系統
開戶表
中儲存一條使用者資料,同時此刻使用者已經可以進行訂單充值了 -
使用者正式使用我方裝置時,通過我方驗證,我方系統將會把使用者資料由
開戶表
中轉移到線上表
中 -
使用者使用過程中,可以進行充值餘額等操作,同時我方可以通知第三方的餘額變化
-
使用者有了充值訂單以後,後續使用過程中,可以進行取消訂單的操作,同時取消後也會通知第三方
-
注:取消訂單的前提是,使用者資料存在於我方系統中的
開戶表
或者線上表
中
問題出現
某次測試同學使用時,發生使用者存在於我方開戶表
按照上面的流程圖,應該不會發生這種情況,最後查到的原因是,
有一種場景,第三方系統可以直接指定使用者在某臺裝置中直接使用,而不是先開戶,後面由使用者自己登入使用第三方裝置,
當直接使用這種場景時,根據我方系統的log日誌觀察,第三方會同時傳送兩次請求,
-
傳送開戶通知
-
傳送使用請求
由於介面是同時請求的,因為網路各種原因,很有可能是使用通知先執行,這時候我方系統去刪除開戶表
中的資料,雖然沒有,但是不會影響後面的結果,如果沒有則直接在線上表
中插入一條使用者資料,因為我們這裡的強制需求是不能影響使用者正常裝置,所以即使開戶表
當這種情況發生時,先執行了使用介面
,後面又跟了一個開戶介面
,導致使用者實際上已經進行使用了,但是後面又在開戶表
中添加了一條使用者資料,
當用戶登出使用的時候,我們只會刪除線上表
中的資料,沒有刪除開戶表
中的資料,導致後面取消訂單的時候,通過了我方系統的驗證,但是去通知第三方系統的時候,其實使用者已經登出了,導致第三方無法找到該使用者更新資訊出錯。
但是有的時候,又因為開戶介面
先請求到,使用介面
後請求到,導致流程是順暢的,所以沒有這個問題,這種詭異的情況。
解決方案
-
在
使用介面
使用Thread.sleep(1000)
這種方式,這樣讓開戶介面
先執行,使用介面
後執行,當然這個行不通,萬一開戶介面
-
兜底,當用戶登出使用的時候,同時刪除
開戶表
和線上表
中的相關使用者資料,這樣取消訂單時就不會發生烏龍了,這個是最終為了影響最小所接收和使用的方案。 -
跟第三方溝通指定裝置使用時,兩個介面合併為一個或序列請求,這個涉及到業務方的交涉,此處不討論。
總結
這是對第三方的介面通知各方面以及裝置使用沒有作更完善的瞭解,導致的問題,因為不清楚直接指定裝置使用,會同時請求兩個介面,我方系統沒做好非同步的控制,後續與第三方系統對接時,儘量瞭解更多的場景,作更多的思考。