后台任務利器之Hangfire


后台任務利器之Hangfire

一.簡述

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

二.安裝

Hangfie官方支持是MsSql和redis,除此之外,可供選擇的還有PostgreSqlMongo
在應用入口項目需要引用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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM