介紹
前面介紹Quartz.Net的基本用法,但在實際應用中,往往有更多的特性需求,比如記錄job執行的執行歷史,發郵件等。
閱讀目錄
- Quartz.Net插件
- TriggerListener,JobListener
- Cron表達式
- Quartz.Net線程池
- 總結
Quartz.Net插件
Quartz.net 自身提供了一個插件接口(ISchedulerPlugin)用來增加附加功能,看下官方定義:
public interface ISchedulerPlugin { void Initialize(string pluginName, IScheduler sched); //關閉調度器 void Shutdown(); //插件啟動 void Start(); }
繼承接口,實現自己的插件。
public class MyPlugin : ISchedulerPlugin { public void Initialize(string pluginName, IScheduler sched) { Console.WriteLine("實例化"); } public void Start() { Console.WriteLine("啟動"); } public void Shutdown() { Console.WriteLine("關閉"); } }
主函數里面配置要實現的插件,注釋部分,一句話搞定。
static void Main(string[] args) { var properties = new NameValueCollection(); //MyPlugin 自定義名稱。 "命名空間.類名,程序名稱" properties["quartz.plugin.MyPlugin.type"] = "QuartzDemo3.MyPlugin,QuartzDemo3"; var schedulerFactory = new StdSchedulerFactory(properties); var scheduler = schedulerFactory.GetScheduler(); var job = JobBuilder.Create<HelloJob>() .WithIdentity("myJob", "group1") .Build(); var trigger = TriggerBuilder.Create() .WithIdentity("mytrigger", "group1") .WithCronSchedule("/2 * * ? * *") .Build(); scheduler.ScheduleJob(job, trigger); scheduler.Start(); Thread.Sleep(6000); scheduler.Shutdown(true); Console.ReadLine(); }
運行結果如下:
TriggerListener,JobListener
這2個是對觸發器和job本身的行為監聽器,這樣更好方便跟蹤Job的狀態及運行情況。
ITriggerListener是官方定義的接口,這里我們直接繼承實現。
public class MyTriggerListener : ITriggerListener { private string name; public void TriggerComplete(ITrigger trigger, IJobExecutionContext context, SchedulerInstruction triggerInstructionCode) { Console.WriteLine("job完成時調用"); } public void TriggerFired(ITrigger trigger, IJobExecutionContext context) { Console.WriteLine("job執行時調用"); } public void TriggerMisfired(ITrigger trigger) { Console.WriteLine("錯過觸發時調用(例:線程不夠用的情況下)"); } public bool VetoJobExecution(ITrigger trigger, IJobExecutionContext context) { //Trigger觸發后,job執行時調用本方法。true即否決,job后面不執行。 return false; } public string Name { get { return name; } set { name = value; } } }
主函數添加:
//添加監聽器到指定的trigger scheduler.ListenerManager.AddTriggerListener(myJobListener, KeyMatcher<TriggerKey>.KeyEquals(new TriggerKey("mytrigger", "group1"))); ////添加監聽器到指定分類的所有監聽器。 //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup")); ////添加監聽器到指定分類的所有監聽器。 //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup")); ////添加監聽器到指定的2個分組。 //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.GroupEquals("myJobGroup"), GroupMatcher<TriggerKey>.GroupEquals("myJobGroup2")); ////添加監聽器到所有的觸發器上。 //scheduler.ListenerManager.AddTriggerListener(myJobListener, GroupMatcher<TriggerKey>.AnyGroup()); scheduler.Start();
JobListener同理,這里不多做描述。
Cron表達式
quartz中的cron表達式和Linux下的很類似,比如 "/5 * * ? * * *" 這樣的7位表達式,最后一位年非必選。
表達式從左到右,依此是秒、分、時、月第幾天、月、周幾、年。下面表格是要遵守的規范:
字段名 | 允許的值 | 允許的特殊字符 |
---|---|---|
Seconds | 0-59 | , - * / |
Minutes | 0-59 | , - * / |
Hours | 0-23 | , - * / |
Day of month | 1-31 | , - * ? / L W |
Month | 1-12 or JAN-DEC | , - * / |
Day of week | 1-7 or SUN-SAT | , - * ? / L # |
Year | 空, 1970-2099 | , - * / |
特殊字符 | 解釋 |
, | 或的意思。例:分鍾位 5,10 即第5分鍾或10分都觸發。 |
/ | a/b。 a:代表起始時間,b頻率時間。 例; 分鍾位 3/5, 從第三分鍾開始,每5分鍾執行一次。 |
* | 頻率。 即每一次波動。 例;分鍾位 * 即表示每分鍾 |
- | 區間。 例: 分鍾位 5-10 即5到10分期間。 |
? | 任意值 。 即每一次波動。只能用在DayofMonth和DayofWeek,二者沖突。指定一個另一個一個要用? |
L | 表示最后。 只能用在DayofMonth和DayofWeek,4L即最后一個星期三 |
W | 工作日。 表示最后。 只能用在DayofWeek |
# | 4#2。 只能用DayofMonth。 某月的第二個星期三 |
實例介紹
”0 0 10,14,16 * * ?" 每天10點,14點,16點 觸發。
"0 0/5 14,18 * * ?" 每天14點或18點中,每5分鍾觸發 。
"0 4/15 14-18 * * ?" 每天14點到18點期間, 從第四分鍾觸發,每15分鍾一次。
"0 15 10 ? * 6L" 每月的最后一個星期五上午10:15觸發。
Quartz.Net線程池
線程池數量設置:
properties["quartz.threadPool.threadCount"] = "5";
這個線程池的設置,是指同時間,調度器能執行Job的最大數量。
quartz是用每個線程跑一個job。上面的設置可以解釋是job並發時能執行5個job,剩下的job如果觸發時間恰好到了,當前job會進入暫停狀態,直到有可用的線程。
如果在指定的時間范圍依舊沒有可用線程,會觸發misfired時間。
quartz 提供了IThreadPool接口,也可以用自定義線程池來實現。
配置如下:
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
一般來說作業調度很少並發觸發大量job,如果有上百個JOB,可在服務器承受范圍內適量增加線程數量。
總結
官方有LoggingTriggerHistoryPlugin,LoggingJobHistoryPlugin 已實現的,觸發器和job歷史記錄的插件。
Quartz.Plugin 命名空間下有官方實現的其他一些插件,也可以自己增加擴展。
quartz中監聽器還有SchedulerListener,使用方法基本一樣。
本文基於自用經驗和官方文檔代碼來寫的,部分是直接翻譯的。
Quartz.Net官方教程http://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/index.html