五年java開發生涯中一次吐血的項目救火(程序員何苦難為程序員)
1,未掌握log日誌的精髓
log日誌的debug,info,error信息亂打,該用debug的用info,該用info的用debug......,導致的結果就是一個登陸成功請求,後臺日誌打了300行代碼,嚴重影響了排查追蹤問題的效率,項目線上日誌級別仍為debug級別,換成info級別呢,結果好多關鍵信息又沒有打印。
日誌輸出格式的關鍵信息不完善,該日誌是在哪類目名、發生的線程,以及在代碼中的行數都沒有清楚的顯示出來,這個日誌是哪裏打印的都無從知曉。
關於這裏,我想說的是,會的框架再多,spark,flink,hadoop,消息中間件等各種上層框架配置的在溜只是花拳繡腿,log日誌是內功,它是日後面對各種線上問題能夠快速排查的一種手段。
下面這個是他的日誌輸出:
2,核心參數不做判斷
方法返回的數據不做null或""字符串判斷,導致各種情況的空指針異常。項目的功能都是理想化,預想我就是需要這些數據才能給你正確的結果,否則哪裏出錯我不知道。這個問題導致我在還原案件現場時給我造成極大的困惑,一不留神一個空指針錯誤,我必須對這個錯誤進行加強的判斷處理,好方便我模擬出登錄多次後無法登錄的情況。
另外項目中sql語句的in的使用不規範,結合前面的null判斷沒有,出現一種:"咦,我用這個賬號登錄就成功了,sql是正確的,用這個人的賬號登錄,怎麽就報sql語法不正確啊,明明調用的是同一塊的代碼啊"
很明顯的roleid為"‘字符串的話,這條sql語句的語法是由問題的。
3,局部變量提升為靜態變量
這個是文章開頭提的問題的原因,因為登錄要向單點系統驗證用戶的身份,所以它采用httpclient框架來發送http請求,它在這裏把httpclient的變量作為一個靜態變量,然後在方法裏面復用該對象,然後方法裏面調用完該對象又沒有釋放資源合理的close,這個框架默認會維護一個連接池,如果你申請一個資源使用後不釋放,那麽該資源將不被下一個請求使用,新的請求必須在等待隊列中等待,然後當用戶登錄20次後,把資源池中的請求都耗盡了,新的請求拿不到資源位於等待隊列中不斷等待,導致服務器超時,登錄失敗504錯誤。
當時我看到這個類的靜態變量時httpclient的時候,我心中就飄起不好的預感,此處是一個容易出錯的地方,如果是我,對這個框架,這個類沒有十足的把握,我會它把整成局部變量,這樣在低並發下,就讓GC去幫我回收吧。
改造後:
4,攔截器的路徑規劃混亂
這個問題也為我排查問題造成了阻礙,排查登錄問題,我首先要把它一次登錄成功後後端走的方法軌跡追蹤出來,看到底是哪一個環節的代碼問題,因為沒有任務錯誤信息。他的攔截器呢,一個登錄請求成功攔截器反復執行了三次,中間至少有一次攔截器是沒有做任何有效出來,出現這的問題是他前端業務發送無關的請求,被攔截導致的,這個逼得我通過日誌插樁計數來還原勾勒出它的完整路徑,為我審查代碼找到調用httpclient這一塊的代碼問題提供的機會。
5,亂用try catch
這個也很惡心,它的代碼突然try catch包裝一下,咦,這個家夥得不錯,還對某些異常進行特殊打標記錄,我仔細看了一下代碼,這是什麽鬼啊,catch中怎麽把異常信息吃了,吃了就吃了,你為啥也不打印異常信息,也不throws異常,就這樣兇猛的將異常吃了,明明有問題,它不報,通過它來引發一個新的異常來雪藏真正的問題。
最後我想說,程序員何苦難為程序員,代碼留一線, 日後好相見啥。你也不想自己給自己挖坑後,解決不了,然後來一句"大哥,你忙嗎,我這有個小問題,幫忙看下唄(嗑瓜子)"。
五年java開發生涯中一次吐血的項目救火(程序員何苦難為程序員)