這個問題困擾了我很久, 從開發的時候就發現這個組件在我們項目中是個風險點。
雖然我本身不是負責該模塊開發的,但是基於一顆好奇心,我找了一份網上基礎課程,瞭解了這個組件的基本原理。
不得不慶幸這個決定,因爲上線當天,以及上線後運維期的重大問題,都和這個組件有關,而這些問題都被我暫時處理了。
這個是我的學習筆記:http://note.youdao.com/noteshare?id=ec97c4f425aaaa8513d297e358163255
開發環境遇到的問題:
1、 開發者 A 、B、 C 同時啓動已經集成了定時任務的應用,連接同一個數據庫時,會在 qz_scheduler_state 上爲
每個機器生成一個調度,但實際情況是: 你會發現不一會,qz_locks 這個表會產生死鎖。
qz_lock 表,有兩條數據:STATE_ACCESS TRIGGER_ACCESS
在執行定時任務時,quartz模塊會將這一條數據 for update ,生成行鎖,這樣就能保證定時任務能被唯一執行。
死鎖的發生,具體原因,我搜索了一下:
https://blog.csdn.net/qq_16681169/article/details/74784193
大概有兩種: 一、 A、 B 交叉訪問, 我覺得 quartz 死鎖應該不屬於這種情況。
二、A、B 共享鎖 (for update) , 當 A 需要修改時,共享鎖上升爲 排它鎖, 同時 B 也需要同時修改,
B 也需要將 它的共享鎖上升爲排它鎖,由於 共享鎖 到 排它鎖 存在轉換時間,且兩種所不兼容,
導致鎖等待, 實際中 也可以發現: lock wait 的提示;
2、 單機定時任務,沒有任何問題。
實際生產中遇到的問題:
1、 上線當天,發生了由於 qz_lock 缺少數據(本身應該有兩條,實際只有一條),導致自動任務無法自動開啓。
補充數據後,自動任務可以正常運行。
2、 運行期間,發生主從庫,schedule 調度表數據庫不一致,而同步失敗的情況。
發生這個問題的原因,個人推測有兩個原因:
(1) 我做容災測試時,模擬主從庫宕機,當時部分應用正在跑自動任務,導致主從庫註冊的調度機器不一致。
(2)上線前數據清理少了這個組件的表;
我覺得:
定時任務應該不與應用耦合,遷移出去,其他應用有定時任務的開放接口。
定時任務單點部署,主要是因爲定時任務沒有很大負載。
數據庫,由於quartz 基於數據庫行鎖,可以建立單庫,供 quartz 進行任務數據的固化。