Hangfire 定时调度
支持分布式和数据持久化的 .NET 定时调度框架
1、.NET Core 添加 Hangfire 中间件
MySQL 作为数据持久化存储
C#
using Hangfire;
builder.Services.AddHangfire(x =>
{
x.UseStorage(new MySqlStorage("数据库连接字符串",
new MySqlStorageOptions()
{
TablePrefix = "Hangfire_", // 表名前缀
// TransactionTimeout = TimeSpan.FromMinutes(120), // 设置超时重试时间间隔,默认30min,目前新版已弃用
InvisibilityTimeout = TimeSpan.FromHours(2) // 设置超时重试时间间隔,默认30min
}));
});
app.UseHangfireServer(additionalProcesses: new[] { },
options: new BackgroundJobServerOptions
{
WorkerCount = 40,
Queues = new string[] { "default", "queue1", "queue2", "queue3" }
});
app.UseHangfireDashboard("/hangfire", new DashboardOptions
{
DashboardTitle = "定时任务",
Authorization = new[] { new MyDashboardAuthorizationFilter() }
});
2、添加授权过滤器
C#
using Hangfire.Annotations;
using Hangfire.Dashboard;
using Microsoft.AspNetCore.Http;
public class MyDashboardAuthorizationFilter : IDashboardAuthorizationFilter
{
public bool Authorize([NotNull] DashboardContext context)
{
// 验证不通过时
// context.GetHttpContext().Response.Redirect("/");
// 验证通过时,返回true
return true;
}
}
3、使用扩展组件:输出控制台
C#
using Hangfire.Console;
builder.Services.AddHangfire(x =>
{
// ...
x.UseConsole();
});
4、使用扩展组件:心跳检查
C#
using Hangfire.Heartbeat;
using Hangfire.Heartbeat.Server;
builder.Services.AddHangfire(x =>
{
// ...
x.UseHeartbeatPage(checkInterval: TimeSpan.FromSeconds(2)); // 添加2秒心跳检查
});
app.UseHangfireServer(additionalProcesses: new[]
{
new ProcessMonitor(checkInterval: TimeSpan.FromSeconds(2)) // 添加2秒心跳检查
}, options: new BackgroundJobServerOptions { });
5、使用扩展组件:周期作业管理
C#
using Hangfire.RecurringJobAdmin;
builder.Services.AddHangfire(x =>
{
// ...
x.UseRecurringJobAdmin(Assembly.Load("ITestService")); // 添加作业管理
});
6、添加作业清理和失败过滤器
C#
using Hangfire.Common;
using Hangfire.States;
using Hangfire.Storage;
public class MyJobApplyStateFilter : JobFilterAttribute, IApplyStateFilter
{
public void OnStateApplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
context.JobExpirationTimeout = TimeSpan.FromDays(7); // 作业过期清理时间
if (context.NewState is FailedState failedState)
{
// 重试失败后处理
}
}
public void OnStateUnapplied(ApplyStateContext context, IWriteOnlyTransaction transaction)
{
context.JobExpirationTimeout = TimeSpan.FromDays(7); // 作业过期清理时间
}
}