您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么為kill job引入安全檢查點機制”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么為kill job引入安全檢查點機制”吧!
XXL-JOB-ONION是基于XXL-JOB的二次開發,我們基于XXL-JOB二次開發做了擴展,如添加ONION_BEAN運行模式、完善告警功能。
關于ONION_BEAN模式:
對于不需要分片的定時任務:通過繼承OnionJobHandler接口實現,而不是使用XXL-JOB提供的注解;
對于需要分片的定時任務:通過繼承OnionShardingJobHandler接口實現,而不是使用XXL-JOB提供的注解;
根據我們目前項目中的定時任務考察,發現定時任務大多都有一個共同點:每個定時任務都是從數據庫查詢一批數據出來處理,并且將每條數據轉為一個Runable放入業務隔離的線程池中執行,例如:
@Component
public class OnionXxlJob implements OnionJobHandler<JobParam> {
@Override
public void doExecute(JobParam param) throws Exception {
// 實際從數據庫查詢
List<Integer> orderIds = Arrays.asList(10000, 11111);
// 這里使用并行流模擬將每個訂單放入線程池處理
orderIds.parallelStream().forEach(orderService::handlerOrder);
}
}
由于定時任務每次執行需要處理大批量數據,可能執行一次需要一個半小時,為解決每次版本更新或者應對突發數據量需要修改配置重啟時都需要等待定時任務執行完成、想kill不敢kill的尷尬,我們為xxl-job引入安全檢查點機制,靈感來源于jvm垃圾回收的安全檢查點機制。
為什么說想kill不敢kill?
雖然需要涉及到數據庫的操作都放在事務中,但并不是所有操作都能回滾,例如修改redis緩存數據、ES數據的操作都無法回滾(一般能放到事務提交之后的都放到后面執行),如果處理數據的過程中需要調用第三方接口,那么會更復雜(這點我們已經通過回放機制實現)。
假設幾百個線程同時在處理,突然kill掉執行中的任務,意味著可能幾百條數據處理出現問題,我們不得不找出這些數據,將未完成的步驟完成。
我們先分析下XXL-JOB的kill job流程:xxl-job-admin前端發起kill請求,admin接收后向執行器發起kill請求并攜帶jobId,執行器根據jobId判斷當前任務是否再執行,如果是則取消。
是否有一種方案,當定時任務管理員從后臺發起kill job操作時,先等待任務進入一個安全點再kill任務呢?
我們來看下面這張圖:
流程說明:
1、管理員在admin操作向執行器發起kill請求、或執行器自身為實現阻塞策略向自己發起kill請求;
2、執行器接收到命令后,先獲取JobHandler,通知JobHandler的安全檢查點管理員,不讓新的Runable進入檢查點;
3、詢問JobHandler的安全檢查點計數器,可實現阻塞等待計數器的值為0再kill,或者異步等待計數器為0再kill;
4、XXL-JOB會為每個Job分配一個ID,通過每個JobId持有一個計數器可以隔離同Job不同時間段觸發的任務,當然,XXL-JOB也不允許同時執行多個相同的Job;
安全檢查點:定時任務中Runable調用的業務方法
比如定時關閉超時未支付訂單的定時任務,查詢出的每個超時訂單,都會調用一個關閉訂單的方法,那么這個方法就可以設置為安全檢查點。
由于安全檢查點需要結合業務考慮,因此我們在設計上,只提供一個檢查點注解,讓使用者自己決定將哪個方法設置為安全檢查點、以及是否需要設置安全檢查點。
缺點:通過AOP方式,只能支持將public的方法設置為安全檢查點。
考慮過使用字節碼增強方式,強行將檢查行為插入private方法,但可能會導致應用啟動速度變慢,如果有需要的話,我們再考慮這種方法。
但我們也提供了編程式解決這個缺點,與Spring實現的事務機制一樣,安全檢查點支持注解方式使用,也支持編程式使用。
關于安全檢查管理員角色的設計:
只通過計數器統計當前進入安全檢查點方法的線程數無法做到“原子性”,在任務執行的過程中,每時每刻都有新的Runable進入安全檢查點方法,也每時每刻都有Runable從安全檢查點方法出來。
通過安全檢查管理員控制Runable是否可以進入安全檢查點方法,在等待計數器值變為0之前,不再讓Runable進入安全檢查點,能夠解決“原子性”等待問題。
1、注解方式使用
注解方式使用要求方法必須是public的,與Spring注解式事務一樣,也存在不生效的問題。
2、編程方式使用
編程式使用也僅需三個步驟:
1、先判斷當前是否存在安全檢查點標志,如果存在則可以放棄執行;
2、計數器加一,這是在OnionShardingJobHandler或OnionJobHandler接口中定義的default方法;
3、計數器減一,這是在OnionShardingJobHandler或OnionJobHandler接口中定義的default方法;
到此,相信大家對“怎么為kill job引入安全檢查點機制”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。