今天在做定時任務的時候,遇到了一個比較難搞的問題,這個問題也比較有意思,現在給大家分享一下,這個定時任務的呼叫入口是這樣的,
// 進行 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();
}
}
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 發布!
架構設計@工程設計@服務穩定性之路
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/109182.html
標籤:MySQL
上一篇:Mysql—資料恢復
