准备工作:
代码地址:Quartz代码
首先完成:Quartz(任务调度框架)练习(2)
1:数据库中添加几张表
脚本文件在:Quartz代码
2:引入MySql支持
3:修改Program中依赖注入的代码
#region quartz //任务计划 //------------------------------------- builder.Services.AddHostedService<QuartzHostedService>(); builder.Services.AddSingleton<IJobFactory, JobFactory>(); builder.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=123456;database=A", // 配置数据库连接字符串,自己需要修改链接字符串 ["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); }); //------------------------------------- // 请求获取-(GC回收-主动释放) 每一次获取的对象都不是同一个 builder.Services.AddTransient<MyJob1>(); builder.Services.AddTransient(u => new JobSchedule(jobType: typeof(MyJob1), cronExpression: "0/10 * * * * ?")); builder.Services.AddTransient<MyJob2>(); builder.Services.AddTransient(u => new JobSchedule(jobType: typeof(MyJob2), cronExpression: "0/15 * * * * ?")); //------------------------------------- #endregion quartz
4:修改QuartzHostedService
修改StartAsync方法的代码
/// <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(); }
5.进入项目根目录,开三个 cmd 用来在本地模拟集群
复制下面这条语句,粘贴到 cmd,然后每个 cmd 里面都修改成不同的端口号
dotnet run --urls=http://*:12345
首先先只运行一个程序,然后观察规律
结果会执行job1和job2然后运行俩个程序,再观察规律
同样的代码,但是定时任务并不会同时被两个进程去执行,他只会执行一个,那现在我把最先开始给停下来
此时第二个会执行job1和job2,然后跑三个看看会怎么样
Quartz可以借助数据库,达到即使部署了多台机器,同一个定时任务也不会连续被几台服务机一起执行的结果。如果一台机器突然停止,这时其他机器接过上台机器的接力棒继续跑,从而做到高可用性。
本文来自博客园,作者:Sleepy-Person,转载请注明原文链接:https://www.cnblogs.com/Sleepy-Person/p/16088293.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!