Hangfire
1.Hangfire是什么?
Hangfire是一個后臺作業執行服務組件,可以集成在ASP.NET、ASP.NET Core、控制臺應用程序、Windows服務等。
2.Hangfire特點?
(1)無需Windows服務或單獨的進程。
(2)支持持久化存儲,存儲方式可支持sqlserver、redis,mongodb等。
(3)支持分布式作業處理
(4)支持自動維護 ,無需執行手動存儲清理 - hangfire會盡可能保持清潔并自動刪除舊紀錄。
(5)提供集成化面板,方便查看作業及監控
3.Hangfire作業流程
客戶端:創建作業,序列化數據。
存儲器:存儲作業,存儲序列化后的數據到Job中
服務器:執行作業,Hangfire Server定時輪詢獲取待執行的Job,同時Hangfire Server還負責保持存儲器清潔并自動刪除舊數據。
4.數據庫表說明
(1)Job表生成準備執行計劃數據
(2)State表中記錄作業的狀態變化(狀態:計劃中、等待、處理中、成功、失敗)。
(3)Set表中記錄定時任務信息,到時間后會生產一條數據到job表中
(4)Server表記錄服務器信息
State表狀態:
Scheduled(計劃中)
Failed(失敗)
Enqueued(排隊中)
Processing(處理中)
Succeeded(成功)
Deleted(刪除)
狀態先后變化順序:排隊中->計劃中->處理中->成功
5.如何使用Hangfire
(1)安裝Hangfire使用命令或在NuGet中安裝。
(2)配置Hangfire
ASP.NET Core配置示例:
public class Startup{public void ConfigureServices(IServiceCollection services){services.AddHangfire(x => x.UseSqlServerStorage("<connection string>"));}public void Configure(IApplicationBuilder app){app.UseHangfireServer();//啟動Hangfire服務app.UseHangfireDashboard();//啟動Hangfire面板}}運行無異常并且能查看儀表盤表示配置成功,查看儀表盤地址:https://your-site/hangfire/
6.Hangfire作業類型
(1)“隊列”作業
BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));“隊列”作業執行步驟如下:
① 序列化方法信息及其所有參數。
② 根據序列化信息創建新的后臺作業。
③ 將后臺作業保存到持久存儲。
④ 將后臺作業排入隊列。
⑤ Hangfire Server的Hangfire組件檢查持久存儲查找排隊的后臺作業并執行后刪除作 業,排隊作業由專用的工作線程池處理。
只有在處理成功后才會刪除該作業。即使在作業期間終止了一個過程,Hangfire也會執行補償邏輯以保證每個作業的處理。
(2)”延遲”作業
Hangfire Server會定期檢查計劃,將計劃的作業排入隊列執行。
BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromDays(1));(3)“重復”作業
操作重復執行的作業,重復時間設置可以設定每分、每時、每天、每周、每月和每年,還可以使用CRON表達式指定更復雜的計劃。
RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Daily); //設置時區為本地時區(每天10點49執行一次)RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), "0 49 10 * * ?",TimeZoneInfo.Local);CRON表達式:
每隔5秒執行一次:”*/5 * * * * ?”
每隔一分鐘執行一次:"0 */1 * * * ?"
每天10點49分執行一次:"0 49 10 * * ?"
(4)“連續”作業
連續作業可以過將多個后臺作業鏈接在一起來定義復雜的作業流程。
var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));7.配置作業隊列
配置作業隊列可以配置優先執行作業順序,ASP.NET Core在Startup.Configure中配置。
配置作業隊列代碼示例:
var options = new BackgroundJobServerOptions{Queues = new[] { "a", "default" },// 隊列名稱,只能為小寫WorkerCount = Environment.ProcessorCount * 5, //并發任務數ServerName = "hangfire1",//服務器名稱SchedulePollingInterval= TimeSpan.FromSeconds(3),//未設置輪詢間隔Hangfire默認是15秒輪詢間隔}; app.UseHangfireServer(options);注意:未設置輪詢間隔時Hangfire默認是15秒的輪詢間隔,如果對于實時性要求比較高可以自定義輪詢間隔。
如何添加作業到指定的配置隊列中
配置作業隊列,在創建作業時要加上標識特性,在指定的類或方法上面加上如下標識[Queue("a")]
8.刪除隊列
(1)使用Hangfire儀表板刪除
(2)使用函數刪除
BackgroundJob.Delete("jobID");//返回值為true為刪除成功,否則為失敗
(3)自定義刪除:
作業隊列存儲在存儲器中的job表,如果需要取消隊列可以執 行SQL修改狀態為刪除,SQL示例如下:
UPDATE a SET a.StateName='Deleted' FROM HangFire.Job a(xlock) where Id=4932 and StateName='Enqueued'
說明:因為只有狀態在“排隊中”、“計劃中”的才能刪除。
狀態如下:
Scheduled(計劃中)
Failed(失敗)
Enqueued(排隊中)
Processing(處理中)
Succeeded(成功)
Deleted(刪除)
狀態先后變化順序:排隊中->計劃中->處理中->成功
9.使用Redis存儲
(1).NeGet中引用”Hangfire.Redis.StackExchange”
(2).在ConfigureServices方法中添加以下配置
Services.AddHanfire(x=>x.UseResisStorage(“redis連接字符串”));
說明:Hangfire.Redis.StackExchange非Hangfire官方組件,因官方組件Hangfire.pro是商業產品,需收費。
10使用IIS作為宿主時應用程序池空閑超時影響作業停止解決方案
問題:IIS會在20分鐘不活動后將應用程序池設置為“超時”、此時“重復”作業和“延遲”作業將不會排隊,并且不會處理排隊的作業。
解決:查看官方解決方案?https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html
11.Hangfire儀表盤自定義配置遠程訪問
var httpContext = context.GetHttpContext();
return httpContext.User.Identity.IsAuthenticated;//驗證是否通過
說明:該接口實現的方法返回true=驗證通過,false=驗證不通過
?app.UseHangfireDashboard("/hangfire", new?DashboardOptions
?{
??????Authorization = new[] { new RestrictiveAuthorizationFilter() }
?????//IsReadOnlyFunc = (DashboardContext context) => true, //只讀視圖
?});
public class RestrictiveAuthorizationFilter : IDashboardAuthorizationFilter{private static System.Web.Caching.Cache cache = HttpRuntime.Cache;public bool Authorize([NotNull] DashboardContext context){if (cache["admin"] == null){string userName = context.Request.GetQuery("username");string pwd = context.Request.GetQuery("pwd");if (userName == "admin" && pwd == "123456"){cache.Remove(userName);cache.Insert(userName, pwd, null, DateTime.Now.AddHours(10), System.Web.Caching.Cache.NoSlidingExpiration);return true;}else{return false;}}else{return true;}}}說明:請求/hangfire get方式傳遞參數驗證
context.Request.GetQuery("d") //讀取參數
總結
- 上一篇: 重新发现业务架构:银行数字化转型经验与方
- 下一篇: 使用Houdini快速将图片转换成文字模