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是否会存在性能问题呢?还有其他等在使用过程中可能遇到的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/308693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

五分钟快速搭建Serverless免费邮件服务

1. 引言本文将带你快速基于 Azure Function 和 SendGrid 构建一个免费的Serverless&#xff08;无服务器&#xff09;的邮件发送服务&#xff0c;让你感受下Serverless的强大之处。该服务可以每月免费发送2,5000封&#xff0c;这是完全白嫖啊&#xff0c;感兴趣的&#xff0c;赶…

[Swagger2]SpringBoot集成Swagger

SpringBoot集成Swagger 引入依赖 <!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</…

IdentityServer4 4.x版本 配置Scope的正确姿势

点击上方蓝字"小黑在哪里"关注我吧前言IdentityServer4 是为ASP.NET Core系列量身打造的一款基于 OpenID Connect 和 OAuth 2.0 认证的框架IdentityServer4官方文档&#xff1a;https://identityserver4.readthedocs.io/看这篇文章前默认你对IdentityServer4 已经有一…

[Swagger2]配置Swagger

配置Swaggr 1、Swagger实例Bean是Docket&#xff0c;所以通过配置Docket实例来配置Swaggger。 package com.xxxx.swagger2.config;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.doc…

.Net Core微服务入门全纪录(完结)——Ocelot与Swagger

点击上方蓝字"小黑在哪里"关注我吧前言上一篇【.Net Core微服务入门全纪录&#xff08;八&#xff09;——Docker Compose与容器网络】完成了docker-compose.yml文件的编写&#xff0c;最后使用docker compose的一个up指令即可在docker中运行整个复杂的环境。本篇简单…

[Swagger2]Swaggr配置扫描接口配置Swagger开关

Swagger配置扫描接口 1、构建Docket时通过select()方法配置怎么扫描接口。 Bean public Docket docket() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select()// 通过.select()方法&#xff0c;去配置扫描接口,RequestHandlerSelectors配置如何扫描…

最全.Net学习资料库上线,今日可免费下载各类资源!(附百度云链接)

送资料送资料1 适合学习者&#xff1a;0-10年.Net开发人员2 更新时间&#xff1a;2020年7月24日3 在哪领取&#xff1a;文末扫码免费领取4 包含课程&#xff1a;零基础就业必修/高级开发必修/架构师必修5 配套资料&#xff1a;视频配套源码/最新面试题合集/最新技术书/安装包你…

[Swagger2]拓展:其他皮肤

拓展&#xff1a;其他皮肤 我们可以导入不同的包实现不同的皮肤定义&#xff1a; 1、默认的 访问 http://localhost:8080/swagger-ui.html <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><ve…

如何基于 DDD 构建微服务?

本文将讨论微服务与 DDD 涉及到的概念、策划和设计方法&#xff0c;并且尝试将一个单体应用拆分成多个基于 DDD 的微服务。微服务的定义微服务中的“微”虽然表示服务的规模&#xff0c;但它并不是使应用程序成为微服务的唯一标准。当团队转向基于微服务的架构时&#xff0c;他…

.NET Core ResponseCache【缓存篇(一)】

一、前言源码1、最近一直在看项目性能优化方式&#xff0c;俗话说的好项目优化第一步那当然是添加缓存&#xff0c;我们的项目之所以卡的和鬼一样&#xff0c;要么就是你的代码循环查询数据库&#xff08;这个之前在我们的项目中经常出现&#xff0c;现在慢慢在修正&#xff09…

[Swagger2]分组和接口注释及小结

分组和接口注释及小结 配置API分组 1、如果没有配置分组&#xff0c;默认是default。通过groupName()方法即可配置分组&#xff1a; Bean public Docket docket(Environment environment) {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).groupName(&qu…

Asp.Net Core 中的“虚拟目录”

写在前面现在部署Asp.Net Core应用已经不再限制于Windows的IIS上&#xff0c;更多的是Docker容器、各种反向代理来部署。也有少部分用IIS部署的&#xff0c;IIS部署确实是又快又简单&#xff0c;图形化操作三下五除二就可以发布好一个系统了。在过去Asp.Net MVC 项目部署的时候…

[mybatis]缓存_缓存有关的设置以及属性

缓存有关的设置以及属性 全局配置中的设置 和缓存有关的设置/属性1.cacheEnabletrue&#xff1b;false&#xff1b;关闭缓存(二级缓存关闭)(一级缓存一直可用的)2.每个select标签都有useCache“true”&#xff1b; false&#xff1b;不使用缓存(一级缓存依然使用&#xff0c;二…

EF批量插入太慢?那是你的姿势不对

大概所有的程序员应该都接触过批量插入的场景&#xff0c;我也相信任何的程序员都能写出可正常运行的批量插入的代码。但怎样实现一个高效、快速插入的批量插入功能呢&#xff1f;由于每个人的工作履历&#xff0c;工作年限的不同&#xff0c;在实现这样的一个需求时&#xff0…

[RabbitMQ]什么是MQ

什么是MQ MQ(message queue)&#xff0c;从字面意思上看&#xff0c;本质是个队列&#xff0c;FIFO 先入先出&#xff0c;只不过队列中存放的内容是message 而已&#xff0c;还是一种跨进程的通信机制&#xff0c;用于上下游传递消息。在互联网架构中&#xff0c;MQ 是一种非常…

.NET Core 实现基于Websocket的在线聊天室

什么是Websocket我们在传统的客户端程序要实现实时双工通讯第一想到的技术就是socket通讯&#xff0c;但是在web体系是用不了socket通讯技术的&#xff0c;因为http被设计成无状态&#xff0c;每次跟服务器通讯完成后就会断开连接。在没有websocket之前web系统如果要做双工通讯…

用 Natasha 写个类型调用的架子

一、想法自上篇文章&#xff0c;我一直琢磨整个好点的例子来展示 Natasha 动态编程能力, 于是就写了一个简单的类型调用的架子&#xff0c;耗时40分钟左右, 项目地址&#xff1a;https://github.com/NMSAzulX/TypeCaller二、功能特点a)、简单的注入功能支持无参构造注入支持递…

Natasha v4.0.0.0 动态编程新篇章

一、简介Natasha 基于 Roslyn 的 C# 动态程序集构建库&#xff0c;该库允许开发者在运行时使用 C# 代码构建域 / 程序集 / 类 / 结构体 / 枚举 / 接口 / 方法等&#xff0c;使得程序在运行的时候可以增加新的模块及功能。Natasha 集成了域管理/插件管理&#xff0c;可以实现域隔…

[RabbitMQ]RabbitMQ概念_四大核心概念

RabbitMQ RabbitMQ 的概念 RabbitMQ 是一个消息中间件&#xff1a;它接受并转发消息。你可以把它当做一个快递站点&#xff0c;当你要发送一个包裹时&#xff0c;你把你的包裹放到快递站&#xff0c;快递员最终会把你的快递送到收件人那里&#xff0c;按照这种逻辑 RabbitMQ …

.Net Core in Docker极简入门(下篇)

点击上方蓝字"小黑在哪里"关注我吧Docker-Compose代码修改yml fileup & down镜像仓库前言上一篇【.Net Core in Docker极简入门&#xff08;上篇&#xff09;】讲解了docker的一些基本命令和操作&#xff0c;并成功构建了自己的asp.net core web应用的镜像&#…