【导读】本节我们继续稍微详细讲讲在我没有详细了解源码的前提下来探讨通过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定时触发作业,好像很简单?相关推荐

  1. 自定义控件其实很简单 五

    最近龙体欠安,很多任务都堆着,虽说如此,依然没有停下学习的步伐,虽然偶尔还会有点头痛,但是孤依旧在学习--自赞一个~ 在1/3中我们结束了全部的Paint方法学习还略带地说了下Matri的简单用法,这 ...

  2. 自定义控件其实很简单5/12

    尊重原创转载请注明:From AigeStudio(http://blog.csdn.net/aigestudio)Power by Aige 侵权必究! 炮兵镇楼 最近龙体欠安,很多任务都堆着,虽说 ...

  3. html案例:模拟一个很简单的聊天框

    html案例:模拟一个很简单的聊天框 实现的代码如下: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "htt ...

  4. 地推外人看来好像是很简单的一件事

    地推外人看来好像是很简单的一件事,可是想要真正去做好的话还是比较难的,其中也有很多问题和细节需要解决注意.这边主要来讲下我们做地推时的一些基本要准备的,以及准备这些的过程中需要注意什么.\ \ 1.场 ...

  5. 从壹开始前后端分离 [ Vue2.0+.NET Core2.1] 二十三║Vue实战:Vuex 其实很简单

    前言 哈喽大家周五好,马上又是一个周末了,下周就是中秋了,下下周就是国庆啦,这里先祝福大家一个比一个假日嗨皮啦~~转眼我们的专题已经写了第 23 篇了,好几次都坚持不下去想要中断,不过每当看到群里的交 ...

  6. java获取mysql数据定时执行_mysql 事件处理(定时触发某个任务或存储过程等)

    自MySQL5.1.6起,增加了一个非常有特色的功能–事件调度器(Event Scheduler),可以用做定时执行某些特定任务(例如:删除记录.对数据进行汇总等等),来取代原先只能由操作系统的计划任 ...

  7. 为什么线程池里的方法会执行两次_别以为线程池很简单,来回答下这些问题!...

    前言 线程池可以说是 Java 进阶必备的知识点了,也是面试中必备的考点,可能不少人看了这篇文章后能对线程池工作原理说上一二,但这还远远不够,如果碰到比较有经验的面试官再继续追问,很可能会被吊打,考虑 ...

  8. 感觉 C++ 很简单,但为何这么多劝退的?

    上一个说C++简单的,已经被面试官问死了... 那些面试官最喜欢的就是你在简历上写"精通"或者"熟练掌握"几个字... 我以前也以为自己学明白了,后来经历的面试 ...

  9. linux怎么读其实很简单 微星为你详解Z77主板BIOS设置

    近期,微星科技发布了大量的7系主板,它们全部配备厂商最新的军规三代组件技术,并且同时配备了PCI-E3.0,USB3.0还有SATA3.0技术,所以我们可以称呼它们为微星3.0主板.随着微星Z77主板 ...

最新文章

  1. 带你用深度学习虚拟机进行文本迁移学习(附代码)
  2. 任务五十二:王牌特工
  3. 解决vue初始化数据时的闪烁问题
  4. python编程入门指南怎么样-学习python网络编程怎么入门
  5. 有序数组求中位数问题
  6. 莫烦Pytorch神经网络第五章代码修改
  7. 计算机专业需要汇编语言,重点大学计算机专业系列教材·汇编语言程序设计
  8. mysql语句命令_MySQL语句和命令大全
  9. 毕啸南专栏 | 对话王小川:搜狗不是谁的“变量”,是行业主要玩家
  10. mysql统计某一个数据库中有几张表
  11. Py2,Py3的差异
  12. 批量转换Caltech Pedestrian Dataset中annotations中的.vbb文件为.txt文件
  13. 自己动手打造 mini 型 QQ (一):动手实现局域网仿 QQ 互联
  14. labelme为圆环状物体打标签【tips】
  15. 聊聊 Redis 是如何进行请求处理
  16. echart2文档(简单明白)
  17. 数控弯管机xyz转换ybc的算法_全自动数控弯管机程序功能解析
  18. 【CVPR2022】Beyond Fixation: Dynamic Window Visual Transformer
  19. 《人工智能算法工程师(高级)》
  20. vue项目转换服务器端渲染,vue-server-renderer实现vue项目改造服务端渲染

热门文章

  1. Android之利用EventBus进行数据传递
  2. day63-webservice 01.cxf介绍
  3. js点击图片查看大图,并可以拖动,且滚动滑轮放大缩小
  4. C#编程中的66个好习惯,你有多少个?(转)
  5. django 1.3下关于静态文件staticfiles的设置
  6. 计算机答辩答不上来怎么回答,答辩答不上来怎么办
  7. flac格式转换mp3格式_MP3,FLAC和其他音频格式之间有什么区别?
  8. android listpreference 自定义,Android – 我的ListPreference中的自定义行布局
  9. python测试框架数据生成工具最全资源汇总
  10. luoguP4755 Beautiful Pair