天天看點

.NET Core開源元件:背景任務利器之Hangfire

一.簡述

Hangfire作為一款高人氣且容易上手的分布式背景執行服務,支援多種資料庫。在.net core的環境中,由Core自帶的DI管理着生命周期,免去了在NF4.X環境中配置always running的麻煩,真正做到開箱即用。

二.安裝

Hangfie官方支援是MsSql和redis,除此之外,可供選擇的還有PostgreSql和Mongo。

在應用入口項目需要引用Hangfire.AspNetCore和特定持久庫,比如使用了MsSql資料庫的Hangfire.SqlServer。

而在其他項目(比如bll層的項目),隻需引用基礎的Hangfire.Core就可以了。

三.Startup配置

1.注入Hnagfire服務

services.AddHangfire(x => x.UseSqlServerStorage("<connection string>"));           

2.可選配置

啟動Hangfire服務和對應的web面闆如下:

app.UseHangfireServer();//啟動Hangfire服務
 app.UseHangfireDashboard();//啟動hangfire面闆           

細心的觀衆可能會發現,這兩個方法都有可選參數,可以提供更多的配置。

2.1 配置任務屬性

var jobOptions = new BackgroundJobServerOptions
{
       Queues = new[] { "test","default" },//隊列名稱,隻能為小寫
       WorkerCount = Environment.ProcessorCount * 5, //并發任務數
       ServerName="hangfire1",//伺服器名稱
 };
app.UseHangfireServer(jobOptions);           

Queues

 要處理的隊列清單

對于有多個伺服器同時連接配接到資料庫,Hangfire會認為他們是分布式中的一份子。現實中不同伺服器往往存在着差異,這個時候就需要合理配置伺服器(應用)的處理隊列,舉兩個例子:

1.對于伺服器性能差異的處理,有100個A任務和50個B任務需要處理,假設A伺服器的性能是B伺服器的兩倍,如果不配置隊列,那麼會平分任務給兩個伺服器。如果我們隻讓B伺服器處理B任務,而A伺服器同時處理兩種任務,這樣B就能減少一些壓力。

2.對于伺服器能力差異的處理,假設A伺服器能處理A和B兩種任務,B伺服器隻能處理B任務(沒有處理A任務的方法或對象),如果不配置隊列,預設會讓B也執行A任務,進而産生錯誤。反面一想,如果A伺服器和B伺服器都有共同的接口,B伺服器不實作接口的方法,發起一個專屬于A伺服器隊列的任務,而A伺服器通過注入實作接口的方法,可以達到傳遞任務的效果。

WorkerCount

 并發任務數,超出并發數将等待之前的任務完成

預設的并發任務數是線程(cpu)的5倍,如果IO密集型任務多而CPU密集型的任務少,可以考慮調高并發任務數。

以上是我用到的,當然還有其他配置參數等着你去開發。

2.2.配置通路權限

在實際生産中,我們可能不希望任何人都可以通路面闆,或暫停執行某些任務,這時就需要重寫面闆的權限了。預設情況下,隻有本地通路權限才能使用Hangfire儀表闆。是以需要重寫控制台,以便遠端通路。

var options = new DashboardOptions
{
    Authorization = new[] { new HangfireAuthorizationFilter() }
};
app.UseHangfireDashboard("/hangfire", options);           
public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter
{
        //這裡需要配置權限規則
        public bool Authorize(DashboardContext context)
        {
            return true;
        }
}           

三.使用(官方文檔)

任務類型

Fire-and-forget

 直接将任務加入到待執行任務隊列

Delayed

 在目前時間後的某個時間将任務加入到待執行任務隊列

Recurring

 周期性任務,每一個周期就将任務加入到待執行任務隊列

Continuations

 顧名思義,繼續執行任務

1.簡單入門

using (var connection = JobStorage.Current.GetConnection())
 {
       var storageConnection = connection as JobStorageConnection;
       if (storageConnection != null)
        {
            //立即啟動
           var jobId = BackgroundJob.Enqueue(()=>Console.WriteLine("Fire-and-forget!"));
       }
 }           

當然,不僅僅隻有靜态方法可以執行,Hangfire的任務也是支援.net core的依賴注入的,會構造一個對象并執行對應的方法。

BackgroundJob.Enqueue<SomeClass>(i => i.SomeMethod(someParams))           

2.進階功能

2.1設定任務隊列

[Queue("test")]
public void TestQueue()
{
}           

對于非周期任務,隻需要在執行的方法添加Queue的特性就能指定該任務讓特定的隊列伺服器處理。

而周期任務,則需要先聲明:

RecurringJob.AddOrUpdate(() => Console.WriteLine("Recurring!"),Cron.Daily,queue:"test");           

2.2 使用日志過濾器(點我檢視)

Hangfire支援自定義過濾器,可以對任務在建立時、執行中、執行後等等狀态執行特定特定的操作。

//特定方法過濾器
[LogEverything]
public static void Send() { 
}
//全局過濾器
GlobalJobFilters.Filters.Add(new LogEverythingAttribute());           

四.中文文檔

hangfire是一個不錯的開源背景任務元件,官方沒有中文文檔,是以簡單地用谷歌機翻修改了一下。

文檔在github的位址:https://github.com/jonechenug/Hangfire-Chinese-Doc

docker運作并通路本地8080端口:

docker run --restart always  --name hangfire -d -p 8080:80 daocloud.io/koukouge/hangfirezhdoc
           

本文采用 知識共享署名-非商業性使用-相同方式共享 3.0 中國大陸許可協定

轉載請注明來源:張蘅水

繼續閱讀