日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hangfire定时触发作业,好像很简单?

發布時間:2023/12/4 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hangfire定时触发作业,好像很简单? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
【導讀】本節我們繼續稍微詳細講講在我沒有詳細了解源碼的前提下來探討通過Hangfire定時觸發作業有哪些需要注意的事項

間隔時間內執行作業

舉個栗子,每隔10秒監控系統CPU,若CPU飆高(根據實際業務定義百分比)則在控制臺打印輸出,第一次執行作業若CPU飆高則打印輸出,但在接下來一分鐘內CPU連續飆高則不再打印,若中間有中斷(CPU正常)則恢復正常打印,如此反復循環。

一般來講定時作業都會執行業務,但上述栗子卻根據作業內部邏輯判斷是否執行打印,所以二者還是有所區別

接下來我們一步步來進行大致模擬實現,首先我們利用內存來存儲作業相關操作,然后每隔10秒執行打印方法

_colorify?=?new?Format(Theme.Dark);GlobalConfiguration.Configuration.UseMemoryStorage();using?var?server?=?new?BackgroundJobServer();RecurringJob.AddOrUpdate(()?=>?Print(),?"*/10?*?*?*?*?*",?TimeZoneInfo.Local);Console.ReadLine();

接下來則是執行上述打印方法

public?static?void?Print() {_colorify.WriteLine($"{DateTime.Now}:CPU飆高啦~~~",?Colors.txtSuccess); }

待執行作業方法一定要為公共(public)方法,否則會拋出如下異常

最后我們每隔10秒執行一次作業看看打印輸出時間是否如我們所預期那樣

雖然Hangfire從1.7+開始支持秒級,但對于作業默認的最小間隔時間是15秒,貌似是無法改變。所以上述我們看到的作業間隔時間差是15秒而非10秒

即使針對只觸發一次作業設置為10秒也無濟于事,不知道是否可改變,未深入研究

var?options?=?new?BackgroundJobServerOptions {SchedulePollingInterval?=?TimeSpan.FromMilliseconds(10) }; BackgroundJob.Schedule(()?=>?Print(),?TimeSpan.FromSeconds(10));

之前我們講過若是利用SQLite存儲作業那么將會出現重復并發執行的情況,比如我們如下將其修改為SQLite存儲

GlobalConfiguration.Configuration.UseSQLiteStorage("Data?Source=./hangfire.db;");

此時毫無疑問會出現連續打印情況(在內存中也會偶爾出現,概率沒有SQLit高)

若是必須限制在間隔時間內只能執行一次作業且在內存或SQLite中存儲作業,那么我們可以嘗試使用限流算法(漏桶算法),在指定時間內只允許幾個請求進入(算法參考地址:https://github.com/robertmircea/RateLimiters)

private?static?readonly?FixedTokenBucket?bucket?=?new?FixedTokenBucket(1,?1,?10000);

實例化對應漏桶算法且在10秒內只能透傳1個請求執行作業

public?static?void?Print() {if?(bucket.ShouldThrottle(1)){return;}_colorify.WriteLine($"{DateTime.Now}:CPU飆高啦~~~",?Colors.txtSuccess); }

若在10秒超過1個請求進入則立即返回

接下來我們實現在1分鐘內禁止連續打印CPU飆高的情況,首先我們將1分鐘內時間控制利用內存存儲來實現

var?provider?=?new?ServiceCollection().AddMemoryCache().BuildServiceProvider();cache?=?provider.GetService<IMemoryCache>();

然后我們繼續改造打印方法,在內存中記錄第1次打印的時間,然后對比接下來1分鐘的時間差,若小于則返回,否則打印再次存儲打印的時間

public?static?void?Print() {double?totalMinutes?=?0;if?(cache.TryGetValue("sys_alarm_time",?out?DateTime?time)){var?subtract?=?DateTime.Now.Subtract(time);totalMinutes?=?subtract.TotalMinutes;_colorify.WriteLine($"subtract:{totalMinutes}",?Colors.txtInfo);}if?((int)totalMinutes?<?1?&&?totalMinutes?!=?0){return;}cache.Set("sys_alarm_time",?DateTime.Now);_colorify.WriteLine($"{DateTime.Now}:CPU飆高啦~~~",?Colors.txtSuccess); }

這里唯一需要注意的是在比較時間差1分鐘,不能用Convert.ToInt32來進行強制轉換

if?(Convert.ToInt32(totalMinutes)?<?1?&&?totalMinutes?!=?0) {return; }

利用上述強制轉換不能精確到接近于1分鐘,因為它是銀行家算法四舍五入,更貼切的說是四舍六入,比如為時間差為0.6時,經過強制轉換后結果就為1,所以利用第一種強制轉換則是只取整數部分

雖說作業執行時間長短會略有差異,但利用第1種強制轉換會控制時間差不會和1分鐘相差太多

我們看到上述時間間隔剛好是1分鐘加上默認的時間間隔15秒,能做到這樣基本上差不多了

本節我們借助一個栗子主要講述在控制臺中執行存儲在內存或SQLite中的作業,在實際項目中,使用Hangfire時或多或少都會存在一些問題

比如我們是否考慮將作業存儲在內存中,那么對于間隔時間很短的定時作業,是否會帶來的很大的存儲開銷呢?理論上Hangfire會對其進行處理,又比如如果作業有幾百個間隔時間很短的定時作業,那么Hangfire是否會存在性能問題呢?還有其他等在使用過程中可能遇到的問題。

總結

以上是生活随笔為你收集整理的Hangfire定时触发作业,好像很简单?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。