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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

間隔時間內(nèi)執(zhí)行作業(yè)

舉個栗子,每隔10秒監(jiān)控系統(tǒng)CPU,若CPU飆高(根據(jù)實際業(yè)務(wù)定義百分比)則在控制臺打印輸出,第一次執(zhí)行作業(yè)若CPU飆高則打印輸出,但在接下來一分鐘內(nèi)CPU連續(xù)飆高則不再打印,若中間有中斷(CPU正常)則恢復(fù)正常打印,如此反復(fù)循環(huán)。

一般來講定時作業(yè)都會執(zhí)行業(yè)務(wù),但上述栗子卻根據(jù)作業(yè)內(nèi)部邏輯判斷是否執(zhí)行打印,所以二者還是有所區(qū)別

接下來我們一步步來進(jìn)行大致模擬實現(xiàn),首先我們利用內(nèi)存來存儲作業(yè)相關(guān)操作,然后每隔10秒執(zhí)行打印方法

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

接下來則是執(zhí)行上述打印方法

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

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

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

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

即使針對只觸發(fā)一次作業(yè)設(shè)置為10秒也無濟(jì)于事,不知道是否可改變,未深入研究

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

之前我們講過若是利用SQLite存儲作業(yè)那么將會出現(xiàn)重復(fù)并發(fā)執(zhí)行的情況,比如我們?nèi)缦聦⑵湫薷臑镾QLite存儲

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

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

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

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

實例化對應(yīng)漏桶算法且在10秒內(nèi)只能透傳1個請求執(zhí)行作業(yè)

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

若在10秒超過1個請求進(jìn)入則立即返回

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

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

然后我們繼續(xù)改造打印方法,在內(nèi)存中記錄第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來進(jìn)行強(qiáng)制轉(zhuǎn)換

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

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

雖說作業(yè)執(zhí)行時間長短會略有差異,但利用第1種強(qiáng)制轉(zhuǎn)換會控制時間差不會和1分鐘相差太多

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

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

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

總結(jié)

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

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