1. 程式人生 > >五年java開發生涯中一次吐血的項目救火(程序員何苦難為程序員)

五年java開發生涯中一次吐血的項目救火(程序員何苦難為程序員)

java 架構

我現在就職於一家中型的互聯網企業,去年年底入職的薪資和待遇都很不錯,但是總結起來說的好聽就是全村人的希望,說的不好聽就是一個人幾乎幹了一個項目組的事。下面是我的一次項目救火經歷(背鍋經歷)。就是年後的一個合作公司上線了一個子業務系統,對接公司內部的單點系統。我收到該公司的技術咨詢:項目啟動後沒有規律的突然無法登錄了,重新啟動後,登錄一斷時間後又無法重新登錄,對方技術人員一頭霧水不知道什麽原因,後臺日誌沒有任何錯誤信息。我臨危受命,趕往該項目進行撲火工作,其實本來2天都可以解決的問題,讓我花了5天解決。具體原因待我一一解釋。

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錯誤。

如果想學習Java工程化、高性能及分布式、深入淺出。微服務、Spring,MyBatis,Netty源碼分析的朋友可以加我的Java進階群:582505643,群裏有阿裏大牛直播講解技術,以及Java大型互聯網技術的視頻免費分享給大家。

當時我看到這個類的靜態變量時httpclient的時候,我心中就飄起不好的預感,此處是一個容易出錯的地方,如果是我,對這個框架,這個類沒有十足的把握,我會它把整成局部變量,這樣在低並發下,就讓GC去幫我回收吧。

技術分享圖片

改造後:

技術分享圖片

4,攔截器的路徑規劃混亂

  這個問題也為我排查問題造成了阻礙,排查登錄問題,我首先要把它一次登錄成功後後端走的方法軌跡追蹤出來,看到底是哪一個環節的代碼問題,因為沒有任務錯誤信息。他的攔截器呢,一個登錄請求成功攔截器反復執行了三次,中間至少有一次攔截器是沒有做任何有效出來,出現這的問題是他前端業務發送無關的請求,被攔截導致的,這個逼得我通過日誌插樁計數來還原勾勒出它的完整路徑,為我審查代碼找到調用httpclient這一塊的代碼問題提供的機會。

5,亂用try catch

  這個也很惡心,它的代碼突然try catch包裝一下,咦,這個家夥得不錯,還對某些異常進行特殊打標記錄,我仔細看了一下代碼,這是什麽鬼啊,catch中怎麽把異常信息吃了,吃了就吃了,你為啥也不打印異常信息,也不throws異常,就這樣兇猛的將異常吃了,明明有問題,它不報,通過它來引發一個新的異常來雪藏真正的問題。

最後我想說,程序員何苦難為程序員,代碼留一線, 日後好相見啥。你也不想自己給自己挖坑後,解決不了,然後來一句"大哥,你忙嗎,我這有個小問題,幫忙看下唄(嗑瓜子)"。

五年java開發生涯中一次吐血的項目救火(程序員何苦難為程序員)