搭建基于Redis的Hangfire定時器
Hangfire的定時配置資訊會自動生成在指定到資料庫内,包括關系型資料庫或非關系型資料庫内。目前為止,它在Redis、Oracle上面,可以支援最短15秒的定時周期,其他資料庫是分鐘級别到。以下使用Hangfire+Redis來實作定時任務。
首先建立新的類庫項目 Wsk.Core.Hangfire,然後在Wsk.Core.Package包項目下引用hangfire有關的元件,包括 Hangfire、Hangfire.Core、Hangfire.Redis、Hangfire.Redis.StaskExchange
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIn5GcukDM3YTOwgzN00iM1MDOwkTMwATMyYDMxIDMy0SO4cTN5kTMvwlNwEjMwIzLclDO3UTO5EzLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
"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;
}
View Code
在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的全部内容,歡迎留下寶貴意見。
歡迎加入QQ群:
群号:1079830632