[ASP.NET Core]Hanfire-輕鬆實現網站背景工作或排程

  • 4127
  • 0
  • 2017-10-19

Hangfire是一個開源且商業免費使用的套件庫,另外有專業版須額外付費並提供一些進階功能與各項服務。

它的強大使ASP.NET能夠管理與執行多種類型的後台任務(Background Task),不必依賴再Windows排程或者Sql Server排程才能做到。

日前幫助同事.NET Core專案遇上的需求,每個進入站台的Request在處理回應的同時執行一些背景任務(ex:抓取資料建立此頁面的Cache),如有相同的Request Uri再進來便能更快速地做出回應,剛好看見近來火紅的Hangfire也有支援.NET Core,就順水推舟的用上它來實現需求。

簡介

Hangfire提供豐富的執行時需要考量的功能,如使用佇列控制管理並提供簡易後臺查看、多種套件化的任務儲存機制(Redis、Memory、Sql Server)、多種背景任務類型、IOC支援、可分散式、可控制同時工作處理數&佇列數量等等。

安裝

  1. 核心套件Install-Package Hangfire.AspNetCore
  2. 任務儲存區套件Install-Package Hangfire.MemoryStorage

設定

ConfigureServices註冊Hangfire服務並設定使用Memory Storage,Configure設定啟用Hangfire、後台Dashboard(非必要)

public void ConfigureServices(IServiceCollection services)
{

    services.AddHangfire(configuration => configuration.UseMemoryStorage());

}
public void Configure(IApplicationBuilder app)
{

    app.UseHangfireServer();
    app.UseHangfireDashboard();

}

後臺查看

啟動後可以透過URI /hangfire(預設,可修改)查看任務狀況,後台也有支援OWIN身分驗證

使用說明

Hangfire主要功能提供下列幾種任務類型,並且皆可設定或提供識別id來提供查詢或者操作:

  • Fire-and-forget tasks:提供立即且一次性的射後不理任務,來縮短Request處理時間
    public IActionResult Index()
    {
        /*var id = */BackgroundJob.Enqueue(() => Console.WriteLine("Simple!"));
        return View();
    }
  • Delayed tasks:提供設定一段時間後才執行的任務
    /*var id = */BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromDays(7));
  • Recurring tasks:提供常態的周期性任務,並使用CRON表達式設定排程時間距
    RecurringJob.AddOrUpdate(/*"job-id",*/() => Console.WriteLine("Transparent!"), Cron.Daily);
    
    
    //立即執行
    RecurringJob.Trigger("job-id");
    
  • Continuations:提供複雜工作流程中不同任務的串接
    var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));
    BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));

其他查詢操作任務的方法:

  • 刪除任務
    BackgroundJob.Delete("job-id");
    
    RecurringJob.RemoveIfExists("job-id");
  • 儲存區資料查詢

    using (var connection = JobStorage.Current.GetConnection())
    {
        var jobData = connection.GetJobData("job-id");
        var jobState = connection.GetStateData("job-id");
    }
  • 後台DashBoard API

    var api = JobStorage.Current.GetMonitoringApi();
    
    var succeededJobs = api.SucceededJobs(0, int.MaxValue);
    
    var jobDetails = api.JobDetails("job-id");

     

個人心得

單從套件設計的角度就覺得是非常棒的實作,而且API簡單易套用,也提供並保留許多實務上會需要的調整點或擴充,是個非常值得投資的利器。面對現實中各種妖魔鬼怪的需求,有把萬能小太刀才能防身退敵阿阿~~

延伸閱讀: