程序日誌中止滾動問題排查

今天在作定時任務的時候,遇到了一個比較難搞的問題,這個問題也比較有意思,如今給你們分享一下,這個定時任務的調用入口是這樣的。架構

// 進行 ldap同步
public void  runLdapSyncJob(){
    try {
        ldapSyncService.syncLdap();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

這個方法ldapSyncService.syncLdap()向外拋出異常,這個方法內部會調用另外一個方法

/**
 * 建立部門目錄並返回部門cn
 * @param departmentDtoMap
 * @param targetDepartId
 * @param rootCn
 * @return
 * @throws Exception
 */
public  String creatStaffDepartCN(Map<Long,DepartmentDto> departmentDtoMap ,long targetDepartId,String rootCn, Set<String> ldapDUSet ) throws Exception {}

可是傳入的參數中,第二個參數傳入的是Long類型,並且是null,一開始沒排查出來,由於一直加日誌,在調用處,數據返回處,數據驗證處都加日誌了,可是經過定時任務管理平臺執行任務以後方法執行到必定行數就什麼也沒有了,也沒有日誌,懷疑是可能有死循環(程序裏寫了while)結果top一下,發現cpu,內存都很正常,結合以前遇到的這種狀況也看了下這個定時任務的進程中線程狀態,看看有沒有blocked或者死鎖(單線程操做應該不會有死鎖),發現也沒有。
這就尷尬了,因而想到了可能異常被框架或者jvm吃掉了,因而在上面兩個方法裏都加了try,catch框架

ldapSyncService.syncLdap() throws Exception{
try{
......
}catch(Exception e){
e.print();
}
}jvm

creatStaffDepartCN() throws Exception{
try{
......
}catch(Exception e){
e.print();
}
}線程

再次部署執行以後發現確實有異常了,而後拋出了空指針,這裏我恍然大悟,由於creatStaffDepartCN這個方法的第二個入參確實沒有值傳進去的。而後懷疑是不是由於自動裝箱和拆箱過程當中即便出現異常也會被jvm吃掉。本地簡單寫了一個demo,運行發現會報空指針。
這裏沒有打印異常我判斷有下面幾種可能
1.定時任務框架沒有幫忙拋出。
2.最外層的try,catch沒有生效
3.jvm把異常吃掉了架構設計

下面總結一下遇到程序日誌中止滾動以後咱們能夠作的一些操做
1.top看是否因爲FGC等問題致使的服務中止響應
2.jstack -l pid看一下進程內線程是否大量有blocked狀態的線程
3.在日誌中止滾動的代碼上下文增長try,catch語句嘗試捕獲異常。設計

本文由博客一文多發平臺 OpenWrite 發佈!
架構設計@工程設計@服務穩定性之路指針

相關文章
相關標籤/搜索