准備工作:
- 數據庫一個,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