Java事故排查過程詳細講解
前言
作為一名軟件開發(fā)人員,經(jīng)常會遇到各種各樣的事故,一般憑借日志就可以定位到異常問題,然后修復(fù)測試,即可驗證是否解決,這種較為簡單的問題。
復(fù)雜一點的是,長時間運行出現(xiàn)的問題,比如運行幾天之后,程序發(fā)生異常,這種不是部署上線后立即發(fā)現(xiàn)的,很難排查,但是一般也可以歸結(jié)為并發(fā)性能異常、內(nèi)存漏洞之類異常。這種情況,日志比較少,需要dump程序的信息,進行分析,以內(nèi)存泄露為例來說,需要定位到程序中的大對象,然后查看相關(guān)代碼定位。
還有一類問題,較為困難,也沒有日志,內(nèi)存dump數(shù)據(jù)也看不出什么,程序一直卡主,無從下手,今天就介紹一種。
一、異?,F(xiàn)象
Springboot項目,使用sharding進行分庫分表,程序使用mysql作為數(shù)據(jù)源,上線一直沒問題,現(xiàn)在需要切換到postgres進行測試,發(fā)現(xiàn)程序一直起不來。
二、排查過程
1.查看日志
首先,檢查程序日志,發(fā)現(xiàn)驅(qū)動報錯,很開心,竟然有日志。

但是很快發(fā)現(xiàn),這個日志并不是導(dǎo)致程序卡主的原因,這個錯誤反而導(dǎo)致排查的方向走錯,浪費了時間。
2.查詢堆棧信息
報錯日志沒有作用,排查沒有了方向,為了排查方便,我單獨建個項目,只是使用sharding來驗證,發(fā)現(xiàn)同樣的問題,但是這可以方便后續(xù)排查。
接下來只能看下程序內(nèi)部信息,因為并沒有內(nèi)存溢出之類的問題,也無需排查內(nèi)存dump信息。
接下來想到內(nèi)存棧信息,看下main線程是不是沒有起來,卡主了。
使用jstack命令查看,結(jié)果如下:

3.查詢數(shù)據(jù)庫
初次看到stack信息,也是一頭霧水,看到main方法好像在正常運行,狀態(tài)是正常的。最后在查詢postgres數(shù)據(jù)庫,那么就想到是不是數(shù)據(jù)庫卡主了呢?
執(zhí)行以下SQL來查看當前是否有被阻塞的查詢以及鎖的等待情況:
SELECT
pg_stat_activity.pid,
pg_stat_activity.query,
pg_stat_activity.state,
pg_locks.mode,
pg_locks.granted,
pg_blocking_pids(pg_stat_activity.pid) AS blocking_pids
FROM pg_stat_activity
JOIN pg_locks ON pg_locks.pid = pg_stat_activity.pid
WHERE pg_stat_activity.state = 'active'
AND pg_locks.mode LIKE '%ExclusiveLock%'
AND pg_stat_activity.query NOT LIKE '%pg_stat_activity%'; -- 排除掉這個查詢本身
發(fā)現(xiàn)數(shù)據(jù)庫查詢有點慢,但是呢,好像一直在變化,也不是一個sql一直在卡主。而且把超時時間設(shè)置短了,好像不應(yīng)該是一個大sql導(dǎo)致數(shù)據(jù)庫查詢卡主,如果超時了,日志也會打印出來,看起來是好像一直在執(zhí)行sql查詢。
4.調(diào)查棧方法
現(xiàn)在看起來有沒有了思路,想著看下sharding的源碼,看看哪里一直在執(zhí)行,這也是合理的想法。
Stack棧信息里面也有很多方法,也不知道哪個重要,只知道sharding需要查詢元數(shù)據(jù)??创a,逐漸定位到sharding的loadDefaultTables方法,這里是查詢表,然后去找元數(shù)據(jù)信息,要分庫分表嘛。
自己在這個循環(huán)里面也debug的很多步,想著順利執(zhí)行也沒啥問題,想著是不是表太多了導(dǎo)致的。
于是刪除了所有的表,但是發(fā)現(xiàn)這里還是有數(shù)據(jù),debug看下,都是在查詢哪些表的數(shù)據(jù),竟然發(fā)現(xiàn)是其他shema的數(shù)據(jù)!??!
三、結(jié)論
通過debug’發(fā)現(xiàn),sharding需要查詢這個數(shù)據(jù)庫下面所有的表,進行統(tǒng)計,然后導(dǎo)致特別慢,這個數(shù)據(jù)庫有1萬多張表,看到數(shù)據(jù)庫里面的元數(shù)據(jù)sql查詢也比較慢,估計3s,乘以12000,就是36000s,相當于10個小時。
但是我url上面帶了shema信息,應(yīng)該不會去查詢其他的schema,后面確認這個沒有效果。
將sharding從4.0.1升級到4.1.1版本,schema指定是有效的。
總結(jié)
之前遇到?jīng)]有日志的問題,也是很頭疼的,無從下手,只能各種情況嘗試,效率低,通過這次排查,幫自己梳理了思路,后面就不怕遇到類似的問題了。
到此這篇關(guān)于Java事故排查過程的文章就介紹到這了,更多相關(guān)Java事故排查內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springcloud下hibernate本地化方言配置方式
這篇文章主要介紹了springcloud下hibernate本地化方言配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法
本文主要介紹了Mybatis-Plus使用ID_WORKER生成主鍵id重復(fù)的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07
spring聲明式事務(wù)@Transactional底層工作原理
這篇文章主要為大家介紹分析spring聲明式事務(wù)@Transactional底層工作原理,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪2022-02-02

