quartz 報錯:java.lang.classNotFoundException

最近在作一個調度平臺改造的項目,quartz在測試環境跑的是單機環境,生產上兩臺服務器作集羣。java

測試環境是ok的,生產上線後報錯,一個類java.lang.classNotFoundException(註明:這個類被別人修改了名稱,如今使用的新名字)web

第一次:失敗數據庫

從代碼上排除了對舊的job類的引用(配置文件和類都排除了)緩存

推測是服務器緩存了該類。服務器

嘗試:測試

  清除緩存,重啓服務器,仍然報上述錯誤。編碼

第二次:失敗spa

   將生產上的配置拉到測試環境上,反覆測試,重啓服務器時會自動清除緩存。設計

推測是quartz的那個類爲全局變量,在生產上會作同步。調試

  嘗試:

   在測試環境上再次搭建一臺調度服務器,從生產上將配置和執行所有拉到測試環境上,執行ok

  反覆調試,仍然沒有發現同步的跡象。

  沒有重現生產上的異常,不敢上線了。

第三次:失敗

 那麼這個舊的job類究竟從哪裏調用的?找不到頭緒!會不會保存到數據庫吧?

 當時以爲這個想法很搞笑,從設計的角度上來講,quartz應該不容許將別的類引入到本身的體系吧。

 但也沒路可走,就查看數據庫,看看有沒有保存在數據庫中。你猜對了,它對原本來本的躺在數據庫的表中:

CREATE TABLE QRTZ_JOB_DETAILS(
JOB_NAME VARCHAR(200) NOT NULL,
JOB_GROUP VARCHAR(200) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE VARCHAR(1) NOT NULL,
IS_VOLATILE VARCHAR(1) NOT NULL,
IS_STATEFUL VARCHAR(1) NOT NULL,
REQUESTS_RECOVERY VARCHAR(1) NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (JOB_NAME,JOB_GROUP))
TYPE=InnoDB;

好吧! 查看該字段,發現確實是舊的類,被不是新的類。

那麼爲何在測試環境中發現呢?

進入測試庫,也沒有發現舊的類,好吧。

第四次:成功

再次部署到生產上,仍是報錯:類找不到。

確認問題處在數據庫中,我對quartz的表一張張的查找,仍然找不到這個記錄,那就從寫入庫開始入手,查了quartz的代碼,發現job_detail表中有個字段job_data,它的類型是blob,會不會存在這裏呢?

確實,能夠打開此blob查看,數據時放到這裏了。

這個當心一些,再次檢查是否有別的blob字段存放舊的job類,發如今triggers表中也有個字段job_data,至此問題發現了。可怎麼解決呢?blob類型的數據不能直接經過update來執行,畢竟要考慮到編碼的因素,拿就釜底抽薪,直接將類重構爲之前的類。

從此次經從來看,舊項目果真是坑,我就直愣愣的掉進去了。

結論:

計算機是個理性的東西,故一切皆有可能,即使是最不可能的事情也要去一一確認。在查找問題時最好想清楚全部發生故障的可能,而後一一排除,直到找到最終的問題。

對web開發來講,解決此類問題的通常思路以下:

1,從全局的角度來看,應用程序,緩存,數據庫是三大獨立模塊,這些部分都有可能發生異常,應該首先排查應用程序自己的異常(這個機率最大);其次是緩存(同步)模塊排查;最後是數據庫模塊排查。

2,全局肯定好的前提下,細分上述的模塊,將可能出現的問題一一列出。

3,動手,驗證想法。對一個好的開發者來講,動手只是驗證的手段,思路纔是最重要的。

相關文章
相關標籤/搜索