背景
2018年8月15號下午6點左右一個我們服務的調用方通知我們他們在調用服務接口時出現了大量的異常和通知,並且錯誤返回值都是“顯示未設置結束日期”
問題定位
收到調用方的消息后,我立即展開了問題的排查
1、通過服務管理平台查看服務是否出現超時及比對今天和昨天接口整體的響應時長,但是排查后發現服務正常。
2、通過調用方提供異常用戶id從日志中排查是否出現異常,排查發現日志中也打印了未設置結束日期的錯誤信息,但是還是無法定位問題原因
3、根據調用方提供的返回值信息在項目工程中進行全局搜索,發現這個返回枚舉值除了在添加接口引用並沒有其他接口在引用,此時我就非常納悶為什么這個接口沒有引入這個枚舉日志中卻顯示了這個枚舉值呢。
4、通過上面的情況我想是不是枚舉填充錯位或者被攻擊了,為了證明猜想我在本地寫了一個程序來調用線上服務,發現返回的結果值是正確的,說明服務是正常的,然后又讓調用方按照我的方式繼續調用線上服務,奇怪的是當他們已調用服務這個異常信息就被打印出來
5、這個問題我們已經連續排查第二天的凌晨但是依然找不到原因,最后我們就想重啟下試試,也可能是某個內存或者環境出問題了,我們重啟了其中2台機器,並將這兩台分組給調用方,結果調用方正常了,正當准備回家睡覺然后明天在繼續跟蹤問題的時候發現那個異常又在次出現
6、最后一個同事不經意說是不是有人篡改了枚舉值,我們恍然大悟,立即看這個枚舉是否能被set,果不其然有一個public的set值,然后我們搜索項目中有一個接口分支調用了這個set值
7、問題基本都已經定位完畢,引發這個bug是同事在6點剛好上線,他們在添加時候沒有傳入日期導致了bug被復現
解決方案
我們刪除了set這段代碼,然后采用返回實體,線下驗證正常后進行上線,上線后問題業務方的調用恢復正常。
附加前后2種代碼對比:
后續規避
1、定義部門中的相關規划(如禁止枚舉開放set值)
2、加強代碼review,重要的項目保證2個人同時開發,避免問題的產生