搭建基於Redis的Hangfire定時器
Hangfire的定時配置資訊會自動生成在指定到資料庫內,包括關係型資料庫或非關係型資料庫內。目前為止,它在Redis、Oracle上面,可以支援最短15秒的定時週期,其他資料庫是分鐘級別到。以下使用Hangfire+Redis來實現定時任務。
首先建立新的類庫專案 Wsk.Core.Hangfire,然後在Wsk.Core.Package包專案下引用hangfire有關的元件,包括 Hangfire、Hangfire.Core、Hangfire.Redis、Hangfire.Redis.StaskExchange
在Wsk.Core.Hangfire專案下,新增Hangfire連線Redis的配置實體類:
在配置檔案新增基於redis的hangfire的資料庫連線:
我的配置原始碼:
"Hangfire": { "Config": { "ConnectionString": "127.0.0.1:6379,password=wesky123,connectTimeout=1000,connectRetry=1,syncTimeout=10000", "Db": 3 // 設定Hangfire使用的Redis的DB區 } }
新建HangfireHelper類,並且新增一個用於讀取配置hangfire資訊的方法,用來把讀取的資料,儲存在先前建立的實體類上:
在原先的實體類新增一個JobStorage型別的變數,用來儲存hangfire連線redis的storage:
實體類原始碼:
public class HangfireConnectionOption { /// <summary> /// Redis連線字串 /// </summary> public static string connectionString { get; set; } /// <summary> /// redis的DB區,預設0 /// </summary> public static int db { get; set; } = 0; public static JobStorage hangfireStorage; }
在HangfireHelper類裡面,新增連線redis的方法,並且把連線的物件賦值到上面新增實體類的變數上:
Helper類原始碼:
public class HangfireHelper: IHangfireHelper { private readonly ILogger<HangfireHelper> _logger; public HangfireHelper(ILogger<HangfireHelper> logger) { _logger = logger; } public void ReadHangfireConfig() { try { HangfireConnectionOption.connectionString = AppHelper.ReadAppSettings(new string[] { "Hangfire", "Config", "ConnectionString" }); HangfireConnectionOption.db = Convert.ToInt32(AppHelper.ReadAppSettings(new string[] { "Hangfire", "Config", "Db" })); } catch (Exception ex) { _logger.LogError($"讀取hangfire配置資訊出錯:{ex.Message}"); } } public void HangfireStorage() { // 預設使用Redis進行Hangfire定時排程任務 HangfireConnectionOption.hangfireStorage = new RedisStorage(HangfireConnectionOption.connectionString, new RedisStorageOptions { Db = HangfireConnectionOption.db, // REDIS 的 DB區 FetchTimeout = TimeSpan.FromMilliseconds(10), // 間隔多久讀取一次,最低為15秒,所以此處設定低於15秒也是會預設為15秒 }); } }
然後開放該類對應的介面:
然後為了方便,我把hangfire類庫專案全部通過autofac進行依賴注入註冊:
然後,在Hosted啟動項裡面,新增Hangfire有關的配置資訊的載入:
然後,在WskService裡面,新增Hanfire的註冊和連線:
在Wsk.Core.Hangfire類庫專案下,新建一個過濾器MyHangfireFilter,用於允許遠端訪問Hangfire的視覺化皮膚:
過濾器原始碼:
public class MyHangfireFilter : IDashboardAuthorizationFilter { public bool Authorize(DashboardContext context) { var httpContext = context.GetHttpContext(); return true; // 允許遠端無限制訪問 } }
最後,在Startup啟動類的Configure方法的最下邊,新增Hangfire的一些配置,以及加入上面的過濾器配置,用於可以跨伺服器遠端訪問並且無需密碼;並且設定視覺化皮膚為可讀,用於不提供手動觸發,如果需要嘗試手動觸發的,可以自己改為false:
現在寫一個定時任務做個試驗,新建類HangfireJobs,並且提供一個無參方法FirstJob以及對應介面:
在Startup的cnfigure方法最下方(配置hangfire以後),新增剛剛到定時任務,並設定了一個cron表示式,用來設定定時一秒執行一次的效果:
configure方法有關程式碼:
app.UseHangfireServer(); app.UseHangfireDashboard("/hangfire", new DashboardOptions { IgnoreAntiforgeryToken = true, DashboardTitle = "Hangfire監控頁面", Authorization = new[] { new MyHangfireFilter() }, IsReadOnlyFunc = (DashboardContext context) => true // 設定為只讀 }); RecurringJob.AddOrUpdate<IHangfireJobs>("MyFirstJob", x => x.FirstJob(), "0/1 * * * * ? ");
啟動以後到結果:
可以看到,即使設定的是1秒,但是實際上是15秒才執行一次。我們開啟視覺化面看檢視:
輸入啟動或釋出的程式所在的ip:port/配置的看板,可在如下程式碼進行更改:
視覺化頁面如下所示:
頁面功能,還請各位大佬親自去探索,我就不一一介紹了。
最後,我們們看下hangfire自動寫入到redis的一些配置資訊:
可以看到,redis連線選擇的BD是3,hangfire也自動把一系列配置資訊寫到redis裡面來了。而且程式上面的配置資訊,我們也可以看見。
最後,定時任務的cron表示式,建議做成可配置,可別像我這樣寫死啊~~~
以上就是hangfire的全部內容,歡迎留下寶貴意見。