.net 5中配置Quartz集群
准备工作:
- 数据库一个,mysql、sqlserver等其他数据库均可
- 在上一篇文章中贴出来的单机版本的代码,没有看过的请转到: https://www.cnblogs.com/shapman/p/14218440.html
或者也可以直接下载上一篇及当前这一篇文章的示例源码:https://github.com/book12138/QuartzSample
Quartz.net官方关于配置集群的文档:https://www.quartz-scheduler.net/documentation/quartz-2.x/tutorial/job-stores.html#ramjobstore
本篇文章内容参考自:https://www.cnblogs.com/JulianHuang/p/12720436.html
1、数据库中添加几张表
根据自己的数据库类型,自行进入这个地址复制SQL执行:https://github.com/quartznet/quartznet/tree/master/database/tables
以下内容均以 Mysql 为例
2、修改startup中依赖注入的代码
改为:
services.AddSingleton<ISchedulerFactory>(u => {
DbProvider.RegisterDbMetadata("mysql-custom", new DbMetadata()
{
AssemblyName = typeof(MySqlConnection).Assembly.GetName().Name,
ConnectionType = typeof(MySqlConnection),
CommandType = typeof(MySqlCommand),
ParameterType = typeof(MySqlParameter),
ParameterDbType = typeof(DbType),
ParameterDbTypePropertyName = "DbType",
ParameterNamePrefix = "@",
ExceptionType = typeof(MySqlException),
BindByName = true
});
var properties = new NameValueCollection
{
["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", // 配置Quartz以使用JobStoreTx
["quartz.jobStore.useProperties"] = "true", // 配置AdoJobStore以将字符串用作JobDataMap值
["quartz.jobStore.dataSource"] = "myDS", // 配置数据源名称
["quartz.jobStore.tablePrefix"] = "QRTZ_", // quartz所使用的表,在当前数据库中的表前缀
["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.StdAdoDelegate, Quartz", // 配置AdoJobStore使用的DriverDelegate
["quartz.dataSource.myDS.connectionString"] = "server=localhost;uid=root;pwd=123;database=quartzsample", // 配置数据库连接字符串,自己处理好连接字符串,我这里就直接这么写了
["quartz.dataSource.myDS.provider"] = "mysql-custom", // 配置数据库提供程序(这里是自定义的,定义的代码在上面)
["quartz.jobStore.lockHandler.type"] = "Quartz.Impl.AdoJobStore.UpdateLockRowSemaphore, Quartz",
["quartz.serializer.type"] = "binary",
["quartz.jobStore.clustered"] = "true", // 指示Quartz.net的JobStore是应对 集群模式
["quartz.scheduler.instanceId"] = "AUTO"
};
return new StdSchedulerFactory(properties);
});
注意改一下数据库连接字符串
3、修改 QuartzHostedService 类
修改 StartAsync 这个方法的内容,在 foreach 循环体内部添加一行 if 判断语句
原来的代码为:
需要改成:
/// <summary>
/// 批量启动定时任务
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task StartAsync(CancellationToken cancellationToken)
{
_scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
_scheduler.JobFactory = _jobFactory;
// 循环遍历startup里注册的作业
foreach (var jobSchedule in _jobSchedules)
{
// 判断数据库中有没有记录过,有的话,quartz会自动从数据库中提取信息创建 schedule
if (!await _scheduler.CheckExists(new JobKey(GenerateIdentity(jobSchedule, IdentityType.Job))) &&
!await _scheduler.CheckExists(new TriggerKey(GenerateIdentity(jobSchedule, IdentityType.Trigger))))
{
var job = CreateJob(jobSchedule);
var trigger = CreateTrigger(jobSchedule);
await _scheduler.ScheduleJob(job, trigger, cancellationToken);
}
}
await _scheduler.Start();
}
3、目前集群已配置完成,进入项目根目录,开三个 cmd 用来在本地模拟集群
复制下面这条语句,粘贴到 cmd,然后每个 cmd 里面都修改成不同的端口号
dotnet run --urls=http://*:10086