2020年5月18日 星期一

Quartz.NET 讓你的網站也可以開始自動排程

前言


目前工作的專案如果有排程的需求(ex. 每天寄信、產生報表之類的)

大部分都是寫一隻程式然後放進Windows排程去執行,

如果是要產生報表資料則會用Mysql的event去跑。

日前收到了一包.net core 的source code,發現裡頭用了 Pomelo.AspNetCore.TimedJob 這個

可以定期執行任務的類別庫,才知道原來有這類型工具可以用啊

所以也想在目前手上的mvc.net 專案裡,增加相同的功能。

servey了一下,發現蠻人多推薦Quartz.NET這個套件,

立馬下載來用,果然是好物!


安裝

直接從NuGet直接下載安裝吧









練習

主要需要實作3個相關的介面、類別

建立排程器:IScheduler、StdSchedulerFactory
建立工作:IJobDetail、IJob:
建立觸發器:ITrigger、TriggerBuilder


1. 首先建立工作的類別
[DisallowConcurrentExecutionAttribute]
public class Job_UpdateDeviceOnlineStatus : IJob
{
    public Task Execute(IJobExecutionContext context)
    {
        return Task.Run(()=> {
            //update device online status 
        });
    }
}
工作內容是去檢查遠端device是否連線,先不多述

加上[DisallowConcurrentExecutionAttribute]

可以避免類別instance兩次,代表同時間只執行一次工作


2. 修改Global.asax,讓程式啟動的時候去加入排程工作
IScheduler scheduler = null;

protected void Application_Start()
{
    ...前略
    StartSchedulerJon();
}

protected void Application_End(Object sender, EventArgs e)
{
    scheduler?.Shutdown();
}

private async void StartSchedulerJon()
{
    try
    {
        //建立排程器
        var factory = new Quartz.Impl.StdSchedulerFactory();
        scheduler = await factory.GetScheduler();

        //建立工作
        IJobDetail job = JobBuilder.Create<Job_UpdateDeviceOnlineStatus>()
            .WithIdentity("OnlineStatusUpdate")
            .Build();

        //建立觸發器
        ITrigger trigger = TriggerBuilder.Create()
            .WithSimpleSchedule(x => x
                .WithIntervalInMinutes(5)
                .RepeatForever())
            .WithIdentity("trigger_OnlineStatusUpdate")
            .StartNow()
            .Build();

        await scheduler.ScheduleJob(job, trigger);
        await scheduler.Start();

    }
    catch(Exception ex)
    {
        //log
        Console.Error.Write(ex.Message);
    }
}

trigger的時間有兩種表示方式,另一種是用CRON表示法

想將windows排程工作轉到.net應用程式裡,這種方式或許比較適合
ITrigger trigger2 = TriggerBuilder.Create()
    .WithCronSchedule("0 0/5 * * * * ") //每5分鐘跑一次
    .WithIdentity("trigger_use_cron")
    .StartNow()
    .Build();


3. 修改Web.config
一些排程的參數放在config檔裡(ex. 時間、enable),可以比較彈性的去調整配置
這次先不做~懶


4.IIS 8.0 設定
*IIS需安裝"應用程式初始化"
*修改應用程式集區的進階設定,將「啟動模式」從預設的「OnDemand」改為「AlwaysRunning」
*修改網站的進階設定,把「預先載入已啟用」(Preload Enabled)由預設的 False 改為 True。


後記

簡單的實作就可以有強力大功能,

也要繼續觀查長期執行下來對Server有沒有什麼其它影響

其它詳細的內容請參考官網文件說明



參考
Huanlin學習筆記
官網

沒有留言:

張貼留言

使用MVC Bundle後,CSS參考的相對路徑不對了??

MVC Bundle相當好用,可以把一堆css, js包在一起 bundles.Add(new StyleBundle("~/css/main").Include( "~/Content/Layout/main.css", ...