日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

.Net Core 简单的Hangfire部署Demo

發(fā)布時間:2024/1/8 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 .Net Core 简单的Hangfire部署Demo 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?

什么是Hangfire?

1.是分布式的后端作業(yè)調(diào)度框架,我們只需要關(guān)心業(yè)務(wù)邏輯代碼,而不用關(guān)心調(diào)度機制持。
2.官方原文:在.NET和.NET Core應(yīng)用程序中執(zhí)行后臺處理的簡單方法。無需Windows服務(wù)或單獨的進程。免費開源且可用于商業(yè)應(yīng)用。Easy to set up, easy to use。
3.Hangfire支持?多種持久化方式 , 存儲方式可支持sqlserver、redis,mongodb等等。
4.Hangfire支持所有類型的后臺任務(wù) - 短時間運行和長時間運行,CPU密集型和I/O密集型,一次性和周期性。

Hangfire組件的基本結(jié)構(gòu)

核心組件:客戶端,服務(wù)端,持久化存儲。這些組件既可以分開部署在不同項目中也可以都部署在一個項目中。

客戶端: 創(chuàng)建任務(wù)–>1、配置HangFire數(shù)據(jù)庫連接 2、創(chuàng)建任務(wù)(在創(chuàng)建任務(wù)的時候HangFire會自動將任務(wù)序列化并存儲到數(shù)據(jù))。

服務(wù)端: 執(zhí)行任務(wù)–>1、配置HangFire數(shù)據(jù)庫連接 2、從HangFire數(shù)據(jù)庫系統(tǒng)表讀取客戶端創(chuàng)建的任務(wù)然后開線程并行執(zhí)行,任務(wù)之間不沖突。(服務(wù)端可宿主在Windows服務(wù)、控制臺程序、IIS中…)。

數(shù)據(jù)庫(持久化存儲): HangFire程序框架表–>創(chuàng)建任務(wù)的時候HangFire會自動生成無需關(guān)心,但要注意如果采用現(xiàn)有的數(shù)據(jù)庫,必須保證數(shù)據(jù)庫中沒有重名的表(aggregatedcounter、counter、distributedlock、hash、job、jobparameter、jobqueue、jobstate、list、server、set、state),數(shù)據(jù)庫可采用 MySQL ,MSSQL,Redis等根據(jù)實際的需求來?

儀表盤(管理面板): 展示作業(yè)列表執(zhí)行狀態(tài)和結(jié)果等相關(guān)信息–>在.Net WebForm或.Net MVC 或.NetCore MVC網(wǎng)站程序?qū)?/p>

HangFire?自從1.6+版本后開始支持NetCore。 1.6.17-1.6.22之間基本為對Hangfire.Core的升級。


創(chuàng)建HangFireDemo

? 1.創(chuàng)建個應(yīng)用程序

?2.引用3個Nuguet包

Hangfire.AspNetCore? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?--Hangfire的組件的包
Hangfire.MySql.Core? /? ?Hangfire.Sqlserver? ? ? ? --Hangfire的持久化數(shù)據(jù)庫的包
--權(quán)限包分為2種?任選其一?依賴項不同請自行選擇
Hangfire.Dashboard.Authorization? ? ? ? ? ? ? ? ? ? ? ?--Hangfire的權(quán)限控制包 (依賴項是owin和hangfire.Core) (目前沒找到可視化界面的方法)
Hangfire.Dashboard.BasicAuthorization? ? ? ? ? ? ? --Hangfire被人二次封裝的包。支持可視化界面的植入。支持core等

3.在管道中注入服務(wù) (在Startup.cs? 的ConfigureServices)

//hangfire的任務(wù)需要數(shù)據(jù)庫持久化//Hangfire.AspNetCore//Hangfire.MySql.Core mysql引用 大小寫敏感//Hangfire.SqlServer sqlserver引用 大小寫敏感//hangfire必須需要綁定一個持久化的連接數(shù)據(jù)。 官方推薦的是sqlserver,還有mg,mssql,pgsql,redis都是個人封裝的//連接字符串必須加 Allow User Variables=trueservices.AddHangfire(x => x.UseStorage(new MySqlStorage(Configuration["ConnectionString"] ,new MySqlStorageOptions{TransactionIsolationLevel = IsolationLevel.ReadCommitted, // 事務(wù)隔離級別。默認是讀取已提交。QueuePollInterval = TimeSpan.FromSeconds(15), //- 作業(yè)隊列輪詢間隔。默認值為15秒。JobExpirationCheckInterval = TimeSpan.FromHours(1), //- 作業(yè)到期檢查間隔(管理過期記錄)。默認值為1小時。CountersAggregateInterval = TimeSpan.FromMinutes(5), //- 聚合計數(shù)器的間隔。默認為5分鐘。PrepareSchemaIfNecessary = true, //- 如果設(shè)置為true,則創(chuàng)建數(shù)據(jù)庫表。默認是true。DashboardJobListLimit = 50000, //- 儀表板作業(yè)列表限制。默認值為50000。TransactionTimeout = TimeSpan.FromMinutes(1), //- 交易超時。默認為1分鐘。TablePrefix = "Hangfire" //- 數(shù)據(jù)庫中表的前綴。默認為none})));

ConnectionString是自己的連接字符串。放在配置文件中讀取。連接字符串中必須加上??Allow User Variables=true
MySqlStorage?提供了多個重載方法。可以只注入連接字符串,不添加連接的特性配置。
其中 IsolationLevel?引用的包是? ? using System.Data; ??


4.在管道后端使用

?主要是使用2個服務(wù)

app.UseHangfireDashboard(); //使用hangfire面板app.UseHangfireServer(); //啟動hangfire服務(wù)

?4.1)自定義配置hangfire面板??(在Startup.cs? 的Configure)

?原生的面板如果不指定路徑。默認的進入面板的地址是? (端口號:/hangfire),支持自定義進入hangfire的路徑
?Hangfire.Dashboard.Authorization?包的自定義方法 (方法1)

//添加面板的打開權(quán)限。不是所有人都可以打開面板。可以操作后臺任務(wù)。app.UseHangfireDashboard("", new DashboardOptions{//方法1Authorization = new[]{new BasicAuthAuthorizationFilterOptions{SslRedirect = false, // 是否將所有非SSL請求重定向到SSL URLRequireSsl = false, // 需要SSL連接才能訪問HangFire Dahsboard。強烈建議在使用基本身份驗證時使用SSLLoginCaseSensitive = false, //登錄檢查是否區(qū)分大小寫Users = new[]{new BasicAuthAuthorizationUser{Login ="ycz",//用戶名PasswordClear="123456"// Password as SHA1 hash//Password=new byte[]{ 0xf3,0xfa,,0xd1 }}}}},//方法2Authorization = new[]{new HangfireAuthorizationFilter(){}},});

? --下圖為 方法 2中啟用的自定義規(guī)則類?。需要重寫??IDashboardAuthorizationFilter 的?Authorize 方法

//默認是只能內(nèi)網(wǎng)訪問。 需要重寫這個方法。注入規(guī)則public class HangfireAuthorizationFilter : IDashboardAuthorizationFilter{//這里寫自定義規(guī)則public bool Authorize([NotNull] DashboardContext context){if (context.Request.LocalIpAddress.Equals("127.0.0.1") || context.Request.LocalIpAddress.Equals("::1"))return true;elsereturn false;}}

? 方法 1? 是支持可視化界面的。? 方法 2沒有可視化界面但是開放了接口??IDashboardAuthorizationFilter? 可以重寫自定義規(guī)則?
? 方法 1 和 方法 2 引用的包不一樣,不可同時使用兩種方法。需要注意
? Hangfire.Dashboard.BasicAuthorization (方法1的包)? ? ? ??Hangfire.Dashboard.Authorization? (方法2的包)

? ?而造成2種方法的差異性的就是。

?
? ?啟用面板時的 Authorization 對象在2個包中所支持的類不同,方法1 的包被進行了二次封裝。

? --這個是 方法1 的Authorization 對象所支持的類型

--這個是 方法2?的Authorization 對象所支持的類型

?方法 1 和 方法 2 根據(jù)自己的需求。自行選擇。

? 方法1?可視化界面? ?輸入正確進入儀表盤。? 輸入錯誤會刷新界面?繼續(xù)在當前登錄頁。?
? 方法2?攔截器驗證? ?通過驗證直接進入儀表盤。?沒通過驗證返回 401
?

? 4.2)自定義配置hangfire服務(wù)

//配置要處理的隊列列表 ,如果多個服務(wù)器同時連接到數(shù)據(jù)庫,會認為是分布式的一份子。可以通過這個配置根據(jù)服務(wù)器性能的按比例分配請求,不會導致服務(wù)器的壓力。不配置則平分請求var jobOptions = new BackgroundJobServerOptions{Queues = new[] { "test", "default" },//隊列名稱,只能為小寫WorkerCount = Environment.ProcessorCount * 5, //并發(fā)任務(wù)數(shù) --超出并發(fā)數(shù)。將等待之前任務(wù)的完成 (推薦并發(fā)線程是cpu 的 5倍)ServerName = "hangfire1",//服務(wù)器名稱};app.UseHangfireServer(jobOptions); //啟動hangfire服務(wù)

? ? hangfire的服務(wù)是可以自定義任務(wù)的分發(fā)的。因為框架是支持分布式,可以根據(jù)任務(wù)量根據(jù)服務(wù)器的性能選擇性的根據(jù)優(yōu)劣比重進行分配任務(wù),不然默認是平分任務(wù)。

?

5.配置完成

? 起服務(wù)。? ip:端口號/hangfire? (沒自定義面板配置是hangfire,不然是自己定義的路由)進入可視化面板

??

?同時你的數(shù)據(jù)庫里會創(chuàng)建12張表持久化你的任務(wù)

?

6.添加任務(wù)

? hangfire的任務(wù)分為多種? ? ? ?

? 隊列任務(wù)

??基于隊列的任務(wù)處理是Hangfire中最常用的,客戶端使用BackgroundJob類的靜態(tài)方法Enqueue來調(diào)用,傳入指定的方法(或是匿名函數(shù)),Job Queue等參數(shù),會立即添加到隊列中執(zhí)行.
? 在任務(wù)被持久化到數(shù)據(jù)庫之后,Hangfire服務(wù)端立即從數(shù)據(jù)庫獲取相關(guān)任務(wù)并裝載到相應(yīng)的Job Queue下,在沒有異常的情況下僅處理一次,
? 若發(fā)生異常,提供重試機制,異常及重試信息都會被記錄到數(shù)據(jù)庫中,通過Hangfire控制面板可以查看到這些信息。
? 任務(wù)執(zhí)行不是同步的而是放到一個持久化隊列中,然后將請求控制權(quán)返回給調(diào)用者,不會堵塞

BackgroundJob.Enqueue(() => Console.WriteLine($@"隊列任務(wù)"));

? 延時任務(wù)

??延遲(計劃)任務(wù)跟隊列任務(wù)相似,不是立即調(diào)用而是設(shè)定一個未來時間點再來執(zhí)行。最小的延時類型為秒級別的

BackgroundJob.Schedule(() => A(), TimeSpan.FromMinutes(1));

?定時任務(wù)

? ? 定時循環(huán)任務(wù)執(zhí)行:一行代碼添加重復執(zhí)行的任務(wù),其內(nèi)置了常見的時間循環(huán)模式,也可基于CRON表達式來設(shè)定復雜的模式?

? 第一種 時間格式 (萬能時間匹配)

? * 52 15 12 4 *??

? 這種字符串就是corn表達式?格式是? {秒數(shù)} {分鐘} {小時} {日期} {月份} {星期} {年份(可為空)} 空格間隔
? *代表的是通配?任意? ?是只有在星期的時候可以占位的符號?代表這個時間不在意的,不會影響匹配? ?

?* 52 15 12 4 ?

? ?第二種 時間格式 (循環(huán)時間匹配)
? ?Corn.Minutely? ? ? ? ? 是定時任務(wù)最小的循環(huán)單位,代表每分鐘執(zhí)行一次。還支持的 年 月 日 小時的循環(huán)執(zhí)行

? ?第三種?時間格式 (自定義時間)
? ?Cron.Daily(18,36)? ? 支持多種重載方法?第一個參數(shù)是小時,第二個參數(shù)是分鐘。
? ?(這種方法的本質(zhì)其實也是底層使用的Cron表達式 ,不過這里只有5位/6位和cron定義的最多7位有差異。應(yīng)該是省略了年)

??
? ?如果是要指定的時間執(zhí)行要注意時區(qū)問題。默認的是UTC的時區(qū)。想要使用當前時間則需要指定時間類型?TimeZoneInfo.Local

RecurringJob.AddOrUpdate("1",() => A(), "* 52 15 12 4 *"); //每年的4月12號15點52分任意秒執(zhí)行 沒加時區(qū) 小時+8RecurringJob.AddOrUpdate("2",() => A(), Cron.Minutely); //每分鐘執(zhí)行一次。RecurringJob.AddOrUpdate("3",() => A(), Cron.Daily(18,36),TimeZoneInfo.Local); //每天18點36分 當前時區(qū)

? 延續(xù)性任務(wù)執(zhí)行?

??延續(xù)性任務(wù)類似于.NET中的Task,可以在第一個任務(wù)執(zhí)行完之后緊接著再次執(zhí)行另外的任務(wù):

BackgroundJob.ContinueWith("1", () => B());

?延續(xù)性批處理?和 批處理

?pro版本 ?(需要商業(yè)授權(quán)和收費)?這里實現(xiàn)的效果應(yīng)該和上面雷同 (這里沒有自己具體測試下面的功能)

//延續(xù)性批處理 BatchJob.StartNew(x =>{x.Enqueue(() => Console.WriteLine("Job 1"));x.Enqueue(() => Console.WriteLine("Job 2"));});//批處理BatchJob.ContinueWith(batchId, x =>{x.Enqueue(() => Console.WriteLine("Last Job"));});

?里面的方法可以自定義多種類型我這里只是這三種了


個人總結(jié):

? ?1.只有定時任務(wù)和延續(xù)性任務(wù)支持自定義編號,如果不自己定義就會默認將方法名設(shè)置為編號? 在可視化界面中

?2.所有的記錄方法都會被持久化到數(shù)據(jù)庫里。如果關(guān)閉了服務(wù)。下次再開啟。之前的周期性任務(wù)依然會存在?依然會被執(zhí)行

3.冗余規(guī)則(因為持久化的原因?服務(wù)的調(diào)用可能會重復執(zhí)行定時任務(wù),所以針對規(guī)則選擇定時任務(wù)的位置啟動在哪)

我定義了6個定時任務(wù)。不斷重復啟動,但是任務(wù)列表中只有這3個定時任務(wù)。說明規(guī)則冗余規(guī)則是:

無編號下?取方法為編號。同編號的任務(wù)只會存在一條,而時間取最后執(zhí)行的那次時間為準
有編號下?編號相同不會重復存在定時任務(wù)。

?

本文參考鏈接:https://blog.csdn.net/long870294701/article/details/87810621

?


?

總結(jié)

以上是生活随笔為你收集整理的.Net Core 简单的Hangfire部署Demo的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。