quartz.net 可视化改造
2022-01-03 16:55 mi-战斧 阅读(504) 评论(0) 收藏 举报Part 1
为什么使用可视化quratz?我之前使用quartz.net 写了一个定时任务系统,是利用quartz.net 结合 IHostedService 写的,任务配置通过plugin quartz.config 读入 quratz_jobs.xml的配置文件生成。每次需要新增job需要的步骤为:
这里一直存在的问题是我没有办法随时随地修改配置Job的执行频次,以及决定Job是不是立即执行用于初始化之类的操作。
所以我一直想要一个可以可视化编辑定时任务的界面。
Part2
我查了网上的资料,以及开源的系统,其中Quartzui 是做的最好的,通用性最强,但是他只能使用URL来激活Job,那么根据他的配置方案,是通过定时轮询调用 API 来达到调用Job执行的目的,这里存在一个问题,我的任务可能是耗时很长的操作,比如我需要计算一个月产生数据报表,这个时候可能需要二十多分钟,一个api耗时几十分钟,我内心是不能接受的,虽然这个API肯定不对外,其他程序也不回调用,但是内心很排斥(我也不知道为啥)。
我理想的方案是可视化直接可编辑我的Job的配置Trigger,这样势必造成不够通用。
quartz.net 的示例。
// Grab the Scheduler instance from the Factory
StdSchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = await factory.GetScheduler();
// and start it off
await scheduler.Start();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("job1", "group1")
.Build();
// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInSeconds(10)
.RepeatForever())
.Build();
// Tell quartz to schedule the job using our trigger
await scheduler.ScheduleJob(job, trigger);
// some sleep to show what's happening
await Task.Delay(TimeSpan.FromSeconds(60));
// and last shut down the scheduler when you are ready to close your program
await scheduler.Shutdown();
这里可以看到Job是需要主导到Scheduler中的,qurartz Pulgin 是使用schduler加载xml中的配置,这个配置可以动态加载的,即可以改动xml配置后,立即生效。
那么我们的思路可以是这样:通过系统配置修改quartz_job.xml。如果是PRD环境,需要系统生成文件再替换掉原配置文件,这样需要手撸一个生成job xml 生成器,再做一个指定位置的下发。考虑到你的配置系统跟你的Job系统可能不在一个服务器,那么下发xml又是一个问题。
这样的话,job所在服务器需要有一个解决xml下发问题的逻辑。好麻烦。
于是想了一个一个办法,可视化系统直接使用 quarzui,通过API 激活 指定job执行。
API Job集中在另一个系统中,那么问题来到了 api 激活job🈶不想耗时怎么解决?
part3
答案是我把调用的API系统中同样集成quartz.net,示例如下:
[HttpGet]
[Route("api/job/hello")]
public async Task<string> GetHelloJob()
{
var scheduler = await SchedulerSingleton.CreateInstance();
// define the job and tie it to our HelloJob class
IJobDetail job = JobBuilder.Create<HelloJob>()
.WithIdentity("helloJob", "group1")
.Build();
await scheduler.DeleteJob(job.Key);
// Trigger the job to run now, and then repeat every 10 seconds
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("helloTrigger", "group1")
.StartNow()
.WithSimpleSchedule(x => x
.WithRepeatCount(0))
.Build();
// Tell quartz to schedule the job using our trigger
await scheduler.ScheduleJob(job, trigger);
await scheduler.Start();
return "hello guy";
}
API 中的 Trigger 是立即执行永不重复,那么每次API调用都会激活我们的helloJob 任务。
helloJob 只需要写自己的处理逻辑。同时Job 加上特性DisallowConcurrentExecution,即使API 不停的调用,job也不会有多线程执行,这样就解决了不用造轮子的问题,就是懒。
这里代码同样可以看到每次执行前都会从Scheduler中删除该Job,然后再添加,这样势必造成内存消耗,我的考虑是单次调用这部分损耗很少,但是如果并发量很大,大量API调用操作scheduler 对象,势必会有一定的影响。目前还没有测试,测试后更新。
quartzui的部分可以参考: github https://github.com/zhaopeiym/quartzui
可以讨论一下
浙公网安备 33010602011771号