欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

Hangfire

发布时间:2024/1/8 58 豆豆
生活随笔 收集整理的这篇文章主要介绍了 Hangfire 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

1.Hangfire是什么?

Hangfire是一个后台作业执行服务组件,可以集成在ASP.NET、ASP.NET Core、控制台应用程序、Windows服务等。

2.Hangfire特点?

(1)无需Windows服务或单独的进程。

(2)支持持久化存储,存储方式可支持sqlserver、redis,mongodb等。

(3)支持分布式作业处理

(4)支持自动维护 ,无需执行手动存储清理 - hangfire会尽可能保持清洁并自动删除旧纪录。

(5)提供集成化面板,方便查看作业及监控

3.Hangfire作业流程

客户端:创建作业,序列化数据。

存储器:存储作业,存储序列化后的数据到Job中

服务器:执行作业,Hangfire Server定时轮询获取待执行的Job,同时Hangfire Server还负责保持存储器清洁并自动删除旧数据。

4.数据库表说明

(1)Job表生成准备执行计划数据

(2)State表中记录作业的状态变化(状态:计划中、等待、处理中、成功、失败)。

(3)Set表中记录定时任务信息,到时间后会生产一条数据到job表中

(4)Server表记录服务器信息

State表状态:

Scheduled(计划中)

Failed(失败)

Enqueued(排队中)

Processing(处理中)

Succeeded(成功)

Deleted(删除)

状态先后变化顺序:排队中->计划中->处理中->成功

5.如何使用Hangfire

(1)安装Hangfire使用命令或在NuGet中安装。

(2)配置Hangfire

ASP.NET Core配置示例:

public class Startup{public void ConfigureServices(IServiceCollection services){services.AddHangfire(x => x.UseSqlServerStorage("<connection string>"));}public void Configure(IApplicationBuilder app){app.UseHangfireServer();//启动Hangfire服务app.UseHangfireDashboard();//启动Hangfire面板}}

运行无异常并且能查看仪表盘表示配置成功,查看仪表盘地址:https://your-site/hangfire/

6.Hangfire作业类型

(1)“队列”作业

BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));

“队列”作业执行步骤如下:

① 序列化方法信息及其所有参数。

② 根据序列化信息创建新的后台作业。

③ 将后台作业保存到持久存储。

④ 将后台作业排入队列。

⑤ Hangfire Server的Hangfire组件检查持久存储查找排队的后台作业并执行后删除作 业,排队作业由专用的工作线程池处理。

只有在处理成功后才会删除该作业。即使在作业期间终止了一个过程,Hangfire也会执行补偿逻辑以保证每个作业的处理。

(2)”延迟”作业

Hangfire Server会定期检查计划,将计划的作业排入队列执行。

BackgroundJob.Schedule(() => Console.WriteLine("Reliable!"), TimeSpan.FromDays(1));

(3)“重复”作业

操作重复执行的作业,重复时间设置可以设定每分、每时、每天、每周、每月和每年,还可以使用CRON表达式指定更复杂的计划。

RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), Cron.Daily); //设置时区为本地时区(每天10点49执行一次)RecurringJob.AddOrUpdate(() => Console.Write("Easy!"), "0 49 10 * * ?",TimeZoneInfo.Local);

CRON表达式:

每隔5秒执行一次:”*/5 * * * * ?”

每隔一分钟执行一次:"0 */1 * * * ?"

每天10点49分执行一次:"0 49 10 * * ?"

(4)“连续”作业

连续作业可以过将多个后台作业链接在一起来定义复杂的作业流程。

var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));

7.配置作业队列

配置作业队列可以配置优先执行作业顺序,ASP.NET Core在Startup.Configure中配置。

配置作业队列代码示例:

var options = new BackgroundJobServerOptions{Queues = new[] { "a", "default" },// 队列名称,只能为小写WorkerCount = Environment.ProcessorCount * 5, //并发任务数ServerName = "hangfire1",//服务器名称SchedulePollingInterval= TimeSpan.FromSeconds(3),//未设置轮询间隔Hangfire默认是15秒轮询间隔}; app.UseHangfireServer(options);

注意:未设置轮询间隔时Hangfire默认是15秒的轮询间隔,如果对于实时性要求比较高可以自定义轮询间隔。

如何添加作业到指定的配置队列中

配置作业队列,在创建作业时要加上标识特性,在指定的类或方法上面加上如下标识[Queue("a")]

8.删除队列

(1)使用Hangfire仪表板删除

(2)使用函数删除

BackgroundJob.Delete("jobID");//返回值为true为删除成功,否则为失败

(3)自定义删除:

作业队列存储在存储器中的job表,如果需要取消队列可以执 行SQL修改状态为删除,SQL示例如下:

UPDATE a SET a.StateName='Deleted' FROM HangFire.Job a(xlock) where Id=4932 and StateName='Enqueued'

说明:因为只有状态在“排队中”、“计划中”的才能删除。

状态如下:

Scheduled(计划中)

Failed(失败)

Enqueued(排队中)

Processing(处理中)

Succeeded(成功)

Deleted(删除)

状态先后变化顺序:排队中->计划中->处理中->成功

9.使用Redis存储

(1).NeGet中引用”Hangfire.Redis.StackExchange”

(2).在ConfigureServices方法中添加以下配置

Services.AddHanfire(x=>x.UseResisStorage(“redis连接字符串”));

说明:Hangfire.Redis.StackExchange非Hangfire官方组件,因官方组件Hangfire.pro是商业产品,需收费。

10使用IIS作为宿主时应用程序池空闲超时影响作业停止解决方案

问题:IIS会在20分钟不活动后将应用程序池设置为“超时”、此时“重复”作业和“延迟”作业将不会排队,并且不会处理排队的作业。

解决:查看官方解决方案 https://docs.hangfire.io/en/latest/deployment-to-production/making-aspnet-app-always-running.html

11.Hangfire仪表盘自定义配置远程访问

  • 新添类实现接口IDashboardAuthorizationFilter
  • var httpContext = context.GetHttpContext();

    return httpContext.User.Identity.IsAuthenticated;//验证是否通过

    说明:该接口实现的方法返回true=验证通过,false=验证不通过

  • StartupConfigure方法中添加如下代码:
  •  app.UseHangfireDashboard("/hangfire", new DashboardOptions

     {

          Authorization = new[] { new RestrictiveAuthorizationFilter() }

         //IsReadOnlyFunc = (DashboardContext context) => true, //只读视图

     });

    public class RestrictiveAuthorizationFilter : IDashboardAuthorizationFilter{private static System.Web.Caching.Cache cache = HttpRuntime.Cache;public bool Authorize([NotNull] DashboardContext context){if (cache["admin"] == null){string userName = context.Request.GetQuery("username");string pwd = context.Request.GetQuery("pwd");if (userName == "admin" && pwd == "123456"){cache.Remove(userName);cache.Insert(userName, pwd, null, DateTime.Now.AddHours(10), System.Web.Caching.Cache.NoSlidingExpiration);return true;}else{return false;}}else{return true;}}}

    说明:请求/hangfire get方式传递参数验证

    context.Request.GetQuery("d") //读取参数

    总结

    以上是生活随笔为你收集整理的Hangfire的全部内容,希望文章能够帮你解决所遇到的问题。

    如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。