今天无意中发现了一个很好用的任务调度框架。Hangfire作为一款高人气且容易上手的分布式后台执行服务,支持多种数据库。在 .net core的环境中,由Core自带的DI管理着生命周期。
相较于quartz.net相比,最大的优点是有个自带的监控界面,比较方便。最新版已经支持秒级任务。
基于队列的任务处理(Fire-and-forget jobs)
基于队列的任务处理是Hangfire中最常用的,客户端使用BackgroundJob类的静态方法Enqueue来调用,传入指定的方法(或是匿名函数),Job Queue等参数.(类似MQ)
var jobId = BackgroundJob.Enqueue( () => Console.WriteLine("Fire-and-forget!"));
延迟任务执行(Delayed jobs)
延迟(计划)任务跟队列任务相似,客户端调用时需要指定在一定时间间隔后调用:
var jobId = BackgroundJob.Schedule( () => Console.WriteLine("Delayed!"), TimeSpan.FromDays(7));
定时任务执行(Recurring jobs)
定时(循环)任务代表可以重复性执行多次,支持CRON表达式:
RecurringJob.AddOrUpdate(
() => Console.WriteLine("Recurring!"), Cron.Daily);
延续性任务执行(Continuations)
延续性任务类似于.NET中的Task,可以在第一个任务执行完之后紧接着再次执行另外的任务:
BackgroundJob.ContinueWith(
jobId,
() => Console.WriteLine("Continuation!"));
基于SQL的实现
修改startup.cs类中的ConfigureServices()方法中注入
services.AddHangfire(configuration => configuration .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions { CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), QueuePollInterval = TimeSpan.Zero, UseRecommendedIsolationLevel = true, UsePageLocksOnDequeue = true, DisableGlobalLocks = true })); services.AddHangfireServer();
封装一下
public static void AddHangfireExt(this IServiceCollection services, IConfiguration Configuration) { services.AddHangfire(configuration => configuration .SetDataCompatibilityLevel(CompatibilityLevel.Version_170) .UseSimpleAssemblyNameTypeSerializer() .UseRecommendedSerializerSettings() .UseSqlServerStorage(Configuration.GetConnectionString("HangfireConnection"), new SqlServerStorageOptions { CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), QueuePollInterval = TimeSpan.Zero, UseRecommendedIsolationLevel = true, UsePageLocksOnDequeue = true, DisableGlobalLocks = true })); services.AddHangfireServer(); }
修改ConfigureServices方法
services.AddHangfireExt(Configuration);
修改Configure()方法
//启用监控面板 app.UseHangfireDashboard(); //增加队列任务 backgroundJobs.Enqueue(() => Console.WriteLine("Hello world from Hangfire!")); RecurringJob.AddOrUpdate(() => Console.WriteLine("Recurring!"),Cron.Minutely);
我这里只做了SQL数据库,建议改成redis,提高性能。
Hangfire UI
浏览器打开http://{host:poort}/hangfire/地址,可以看到如下界面:
-
仪表盘
-
可以看到周期性作业列表
还可以加上授权等,先介绍到这里,详细文档可以参考官方文档。