最近解決了一個生產bug,bug的緣由很簡單,就是清理緩存的方式不對。原本沒啥好說的,可是考慮到咱們有時候確實會在一些小問題上栽跟頭,最終決定把這個小故事拿出來跟你們分享下。數據庫
風起
有一天在擼代碼,忽然有我的加我微信,看頭像是個妹子。我第一反應:對方是微商或者賣茶葉的(忍住,別笑)。由於已經有不少次這種加我好友的狀況了,問對方是誰就歷來沒有下文。因此此次我也沒有經過,而是像之前同樣追問了一句「咱們認識嗎」,就沒再管它,心想對方確定不回的。而後繼續而後繼續擼串,哦不,是擼代碼。
還沒1分鐘,對方居然回覆了,大意是「我是xxx公司的某某某,有個問題想諮詢下」,哇哦,原來是客戶。。。趕忙經過驗證並問具體啥問題。原來是對方在點某個頁面按鈕的時候一直提示錯誤,不能正常進行業務了。緩存
常規操做
和以往同樣,我查起了生產log,發現是數據庫鎖表了。客戶是業務型公司,通常不會出現多人同時操做的狀況,數據量也不大,生產上歷來沒有出現過,卻是我本地調試的時候常常由於性子急多點幾回致使鎖表,所以感受這個問題很好解決,讓管理員把鎖解了就好了。微信
雲涌
沒有鎖了,讓客戶再試下,客戶的反饋「仍是報錯」,沒道理啊。再查日誌,發現已經沒有了堆棧信息,爲啥還不行呢。
沒辦法只能看那個時間段全部的log,發現有一行「map緩存中有數據,可能多人同時操做」。
查下代碼,發現代碼中爲了防止同一條數據多人同時操做,加了map做爲緩存,數據記錄的PK做爲key和value。spa
(記住這個圖,後面會考)
每次操做的時候將數據put進map,處理完後remove掉。若是map中有相關KV就表示這條記錄有人正在操做,則其餘人不能操做,拋提示信息。
因而乎問客戶「多人同操乎?」,獲得的答覆是「否」,納尼?怎可能。日誌是不會騙人的啊調試
再查代碼
針對map再把代碼看一遍,看它put和remove的地方,還有日誌打印的地方。終於發現一個問題,
map的清理動做是在try裏面正常處理後作的,若是出現異常就不能正常清理了,而map定義的時候爲了對象間共享定義成了靜態成員變量,
剛纔的鎖表拋了異常,當時已經put進入到map裏面的KV就一直沒有機會清掉了,也就是說只要服務不重啓,問題會一直堅決的陪着你。日誌
對症下藥
1.跟領導申請緊急重啓服務,保證業務正常進行。
2.修改問題代碼,將報錯放到finally塊。
3.橫展開調查其餘相似代碼是否是也存在這個問題,一併修改。對象
風平浪靜
問題解決,對方表示感謝,我也回覆不客氣,一切迴歸平靜。blog
總結
其實這個緩存清理的問題自己很簡單,你們都懂,就和釋放數據庫鏈接等狀況同樣,須要放到finally塊裏面,
這個即便代碼拋異常了也能正常釋放或清理。可是就是擼這段代碼的時候,由於這樣那樣的緣由一時沒有想到。
若是公司有代碼review的環節的話會好不少,若是沒有review,那麼在寫完代碼後最好本身review一遍。
不然,萬一出現相似的問題真的有點尷尬,正如題目所說「清緩存的姿式不對,真的會出生產bug哦」。
但願你我從此都能避免這種狀況的發生。rem