1. 程式人生 > >清快取的姿勢不對,真的會出生產bug哦

清快取的姿勢不對,真的會出生產bug哦

 

最近解決了一個生產bug,bug的原因很簡單,就是清理快取的方式不對。本來沒啥好說的,但是考慮到我們有時候確實會在一些小問題上栽跟頭,最終決定把這個小故事拿出來跟大家分享下。

 

風起
有一天在擼程式碼,突然有個人加我微信,看頭像是個妹子。我第一反應:對方是微商或者賣茶葉的(忍住,別笑)。因為已經有很多次這種加我好友的情況了,問對方是誰就從來沒有下文。所以這次我也沒有通過,而是像以前一樣追問了一句“我們認識嗎”,就沒再管它,心想對方肯定不回的。然後繼續然後繼續擼串,哦不,是擼程式碼。
還沒1分鐘,對方竟然回覆了,大意是“我是xxx公司的某某某,有個問題想諮詢下”,哇哦,原來是客戶。。。趕緊通過驗證並問具體啥問題。原來是對方在點某個頁面按鈕的時候一直提示錯誤,不能正常進行業務了。

 

常規操作
和以往一樣,我查起了生產log,發現是資料庫鎖表了。客戶是業務型公司,一般不會出現多人同時操作的情況,資料量也不大,生產上從來沒有出現過,倒是我本地除錯的時候經常因為性子急多點幾次導致鎖表,因此感覺這個問題很好解決,讓管理員把鎖解了就行了。

 

雲湧
沒有鎖了,讓客戶再試下,客戶的反饋“還是報錯”,沒道理啊。再查日誌,發現已經沒有了堆疊資訊,為啥還不行呢。
沒辦法只能看那個時間段所有的log,發現有一行“map快取中有資料,可能多人同時操作”。
查下程式碼,發現程式碼中為了防止同一條資料多人同時操作,加了map作為快取,資料記錄的PK作為key和value。

(記住這個圖,後面會考)
每次操作的時候將資料put進map,處理完後remove掉。如果map中有相關KV就表示這條記錄有人正在操作,則其他人不能操作,拋提示資訊。
於是乎問客戶“多人同操乎?”,得到的答覆是“否”,納尼?怎可能。日誌是不會騙人的啊

 

再查程式碼
針對map再把程式碼看一遍,看它put和remove的地方,還有日誌列印的地方。終於發現一個問題,
map的清理動作是在try裡面正常處理後做的,如果出現異常就不能正常清理了,而map定義的時候為了物件間共享定義成了靜態成員變數,
剛才的鎖表拋了異常,當時已經put進入到map裡面的KV就一直沒有機會清掉了,也就是說只要服務不重啟,問題會一直堅定的陪著你。

 

對症下藥
1.跟領導申請緊急重啟服務,保證業務正常進行。
2.修改問題程式碼,將報錯放到finally塊。
3.橫展開調查其他類似程式碼是不是也存在這個問題,一併修改。

 

風平浪靜
問題解決,對方表示感謝,我也回覆不客氣,一切迴歸平靜。

 

總結
其實這個快取清理的問題本身很簡單,大家都懂,就和釋放資料庫連線等情況一樣,需要放到finally塊裡面,
這個即使程式碼拋異常了也能正常釋放或清理。但是就是擼這段程式碼的時候,因為這樣那樣的原因一時沒有想到。
如果公司有程式碼review的環節的話會好很多,如果沒有review,那麼在寫完程式碼後最好自己review一遍。
否則,萬一出現類似的問題真的有點尷尬,正如題目所說“清快取的姿勢不對,真的會出生產bug哦”。
希望你我今後都能避免這種情況的發生。