本文介绍了如何掌握Quartz.net分布式定时任务的姿态。内容非常详细。有兴趣的朋友可以参考一下,希望对大家有帮助。
00-1010长话短说,我们今天来谈谈分布式计时任务,我的日志记录:
ASP.NET的核心Quartz.Net实施网络计时任务
AspNetCore结合Redis实践消息队列
经过仔细分析,朋友们知道还是有问题的:
水平扩展的网络应用程序的Quartz.net计时任务将被触发多次,因为网络应用程序实例使用默认的内存作业存储,多个实例在内存中维护作业和触发器的副本。
我的计时任务是同步任务,但是重复执行不是大问题。但是对于具体业务的计时任务,反复执行可能是致命的。
基于此,我们来看看Quartz.net分布式定时任务的姿态。
00-1010显然,水平扩展的多实例需要一个独立于web实例的机制来存储Job和Trigger。
提供Quartz.NET ADO.NET工作商店来存储任务数据。
首先,使用SQL脚本在数据库中生成指定的表结构。执行该脚本后,您将看到数据库中有几个以QRTZ_开头的表
quartz.config使用AdoJobStore以编码或quartz.config的形式添加配置
00-1010
引言
从https://github.com/Quartznet/Quartznet/tree/master/database/tables下载适当的数据库表脚本,以生成指定的表结构。
00-1010通过这次编码添加AdoJobStore配置。
第一次启动会将代码中的作业和触发器保存到sqlite,然后直接从sqlite加载作业和触发器。
使用系统;
使用系统。收藏品。专业化;
使用系统。数据;
使用系统。线程化。任务;
使用微软。Data . Sqlite
使用微软。扩展。日志记录;
使用石英;
使用石英。Impl
使用石英。Impl . AdoJobStore.Common
使用石英。Spi
命名空间EqidManager
{
使用IOCContainer=IServiceProvider
公共类QuartzStartup
{
公共IScheduler Scheduler { get设置;}
私有只读ILogger _ logger
私有只读IJobFactory iocJobfactory
公共QuartzStartup(Iocontainer、ILoggerFactory、LoggerFactory)
{
_logger=loggerFactory。C
reateLogger<QuartzStartup>();
iocJobfactory = new IOCJobFactory(IocContainer);
DbProvider.RegisterDbMetadata("sqlite-custom", new DbMetadata()
{
AssemblyName = typeof(SqliteConnection).Assembly.GetName().Name,
ConnectionType = typeof(SqliteConnection),
CommandType = typeof(SqliteCommand),
ParameterType = typeof(SqliteParameter),
ParameterDbType = typeof(DbType),
ParameterDbTypePropertyName = "DbType",
ParameterNamePrefix = "@",
ExceptionType = typeof(SqliteException),
BindByName = true
});
var properties = new NameValueCollection
{
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
["quartz.jobStore.useProperties"] = "true",
["quartz.jobStore.dataSource"] = "default",
["quartz.jobStore.tablePrefix"] = "QRTZ_",
["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.SQLiteDelegate, Quartz",
["quartz.dataSource.default.provider"] = "sqlite-custom",
["quartz.dataSource.default.connectionString"] = "Data Source=EqidManager.db",
["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz",
["quartz.serializer.type"] = "binary"
};
var schedulerFactory = new StdSchedulerFactory(properties);
Scheduler = schedulerFactory.GetScheduler().Result;
Scheduler.JobFactory = iocJobfactory;
}
public async Task<IScheduler> ScheduleJob()
{
var _eqidCounterResetJob = JobBuilder.Create<EqidCounterResetJob>()
.WithIdentity("EqidCounterResetJob")
.Build();
var _eqidCounterResetJobTrigger = TriggerBuilder.Create()
.WithIdentity("EqidCounterResetCron")
.StartNow()
//每天凌晨0s
.WithCronSchedule("0 0 0 * * ?") Seconds,Minutes,Hours,Day-of-Month,Month,Day-of-Week,Year(optional field)
.Build();
// 这里一定要先判断是否已经从SQlite中加载了Job和Trigger
if (!await Scheduler.CheckExists(new JobKey("EqidCounterResetJob")) &&
!await Scheduler.CheckExists(new TriggerKey("EqidCounterResetCron")))
{
await Scheduler.ScheduleJob(_eqidCounterResetJob, _eqidCounterResetJobTrigger);
}
await Scheduler.Start();
return Scheduler;
}
public void EndScheduler()
{
if (Scheduler == null)
{
return;
}
if (Scheduler.Shutdown(waitForJobsToComplete: true).Wait(30000))
Scheduler = null;
else
{
}
_logger.LogError("Schedule job upload as application stopped");
}
}
}
上面是Quartz.NET 从sqlite中加载Job和Trigger的核心代码
这里要提示两点:
① IOCJobFactory 是自定义JobFactory,目的是与ASP.NET Core原生依赖注入结合
② 在调度任务的时候,先判断是否已经从sqlite加载了Job和Trigger
3.添加Quartz.Net UI轮子
附赠Quartz.NET的调度UI: CrystalQuartz, 方便在界面管理和调度任务
① Install-Package CrystalQuartz.AspNetCore -IncludePrerelease
② Startup启用CrystalQuartz
using CrystalQuartz.AspNetCore;
/*
* app is IAppBuilder
* scheduler is your IScheduler (local or remote)
*/
var quartz = app.ApplicationServices.GetRequiredService<QuartzStartup>();
var _schedule = await quartz.ScheduleJob();
app.UseCrystalQuartz(() => scheduler);
③ 在localhost:YOUR_PORT/quartz地址查看调度
关于如何掌握Quartz.net分布式定时任务的姿势就分享到这里了,希望
内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/102063.html