1. 程式人生 > >spring boot中得定時任務執行一段時間後突然停了 排查過程

spring boot中得定時任務執行一段時間後突然停了 排查過程

在spring boot 專案中設定了一些定時任務,前幾天還執行得好好的,突然有一天就不再執行了,基本上呢都是執行了四天左右,定時任務停掉不在運行了,然後重啟程式定時任務就好使了,出現這麼兩次,第三次是在重啟以後第三天出現定時任務不再執行。感覺莫名其妙,查了好多資料,以下是關於我查到的關於定時任務突然停掉的一些原因。

1)首先查到了大部分經驗說是spring boot中得定時任務都時單執行緒得,要進行多執行緒執行,還要配置

2)如果執行緒本身出現死鎖,ExecutorService一般不會監控到並處理的,所以它會將後續的定時計劃全部delay和pending。

3)如果執行緒的某次定時執行過程中出現了未捕獲的異常,那麼ExecutorService也會將後續的定時計劃全部delay和pending。

4)定時任務執行成功了,於是得出結論: 伺服器系統時間改變後,Spring 定時任務將失效。

5)另外,排查上述的問題也比較簡單,只要每次定時任務執行時打一條log,並在task的最外層捕獲所有Throwable並log就行了
如果你在多個函式上使用了@Scheduled,那麼一定是一個執行完畢,才能排下一個。這往往不是我們想要的效果。

6) 和遠端服務間建立的keep alive的connection過多,導致後面建立的連線會一直連線超時,導致執行緒出現異常。

7) http請求出現某種錯誤時,http請求僵死,導致執行緒也不再往下執行。最終導致後面的定時任務也不再執行。
  之前一直認為http會有一個預設的超時時間(可能是5min),超過這個時間後會報超時異常。這個看法誤導了我。

第一條,我一開始還真以為是單執行緒得,以為就是這個原因,也沒有測試,因為專案中確實只有通過@EnableScheduling 這個註解開啟定時任務得,然後定時任務的方法上使用@Scheduled(cron = "0 0 1 1 * ?")   或者@Scheduled(fixedRate = 1000 * 60 * 5)這樣得策略執行,但是主管說然我測試一下是否為單執行緒執行,感覺springboot 不能這麼low,最後測試的結果確實不是單執行緒執行得,是多執行緒執行得,所以這個原因就pass掉了

第二條,我也不知道怎麼才能出現死鎖,感覺模擬不來,就先擱下了,檢視後面得原因是否與我出現的一樣

第三條,與我的情況一樣,定時任務在執行最後幾次都是正常的,但是突然之間就停掉了,任何報錯都沒有,什麼異常都沒有捕獲到,所以我覺得我的定時任務應該是沒有捕獲到異常導致所有的其他定時任務也執行不下去。但是怎麼解決呢?繼續查詢下去。

第四條、經過反覆檢視,伺服器的時間是沒有改變得,和這個沒有關係(我是檢視伺服器時間沒有變化太大,沒有變成其他時區確定)

第五條、這是一條然你發現定時任務執行到哪一步就不再繼續往下執行,所以我專案中打了很多log,因為定時任務都是去請求其他平臺,所以我在本地獲取資料那打了一條log,在請求完介面返回資料那又打了一條log,通過兩次得定時任務停止,可以看到最後一次定時任務之情本地獲取資料結果,並沒有返回資料結果,也沒有拋異常,我的try()catch{ }在整個得請求介面程式碼中。所以感覺第二條估計是我的病症所在。

第六條和第七條其實是關於上面我的病症解釋和解決

一直奇怪為什麼會出現呼叫的平臺的結果沒有返回而沒有拋異常,定時任務就不再執行下去了呢?終於檢視到了下面這篇部落格

https://www.cnblogs.com/zj0208/p/7018098.html  也就是第六條和第七條。(但是這裡我也瞭解到了我程式碼中請求的另一個平臺在這段時間內確實服務有掛掉或者重啟等操作)

檢視請求其他平臺的得方法,發現是通過httpclient請求的,網上找到了關於HTTP請求時connectionRequestTimeout 、connectionTimeout、socketTimeout三個超時時間的設定。下面這個連結

https://blog.csdn.net/wangjin890620/article/details/54630219

現在剛改程式碼,重新啟動了,等幾天看看定時任務還會停掉嗎?如果沒有再停掉,就說明確實是連線沒有超時所導致得。

------------------------下面也是我找到的一些排查問題-------------------------------

https://blog.csdn.net/stationxp/article/details/80683968

由於httpclient自己沒有預設超時時間的設定,當開發人員沒有設定超時間是的時候,在server的服務端網路出現問題或者一直不返回給客戶端資料結果,就發現client端的請求執行緒一直卡住不會釋放,如果這個是執行緒池中的執行緒,就會一直佔用執行緒池資源,導致執行緒池不能響應後續的的任務。

 

 

靜候佳音中!!!!!!!!