使用 Quartz.NET 实现作业串行执行
Ø 前言
前两天,在公司的一个项目中编写 Windows 服务时,需求是当A服务运行完后,B服务才能运行,B服务运行后,C服务才能运行。因为B服务的数据依赖于A服务生成的数据,而C服务的数据又依赖于B服务。
在之前的文章中有介绍使用 Topshelf 结合 Quartz.NET 创建 Windows 服务,但是当时还不涉及这样的需求,经过后面看过一些相关博客后,便实现了该功能。另外,这里再写个 Demo 研究了一下。
Ø 假设我们有这样一个需求:
1. 就上一篇使用 Topshelf 结合 Quartz.NET 创建 Windows 服务而言,当我们更新商品库存后,我们需要发送短信和邮件通知管理员。
2. 而这两个动作都是两个独立的服务作业,并且它们都相互依赖。
3. 执行顺序:更新商品库存 -> 发送短信 -> 发送邮件,三者都是前一个服务执行完后,接着执行下个服务,下面是具体实现步骤。
1. 首先,我们定义服务配置文件quartz_jobs.xml
<!--该作业用于定时更新商品库存-->
<job>
<name>UpdateInventoryJob</name>
<group>JobGroup1</group>
<description>定时更新商品库存</description>
<job-type>TopshelfAndQuartz.UpdateInventoryJob,TopshelfAndQuartz</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>UpdateInventoryTrigger</name>
<group>UpdateInventoryTriggerGroup</group>
<job-name>UpdateInventoryJob</job-name>
<job-group>JobGroup1</job-group>
<start-time>2017-12-01T00:00:00+08:00</start-time>
<cron-expression>0 0/1 * * * ?</cron-expression>
</cron>
</trigger>
<!--该作业用于发送短信-->
<job>
<name>SendSMSJob</name>
<group>JobGroup1</group>
<description>发送短信作业</description>
<job-type>TopshelfAndQuartz.SendSMSJob,TopshelfAndQuartz</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>SendSMSJobTrigger</name>
<group>SendSMSJobTriggerGroup</group>
<job-name>SendSMSJob</job-name>
<job-group>JobGroup1</job-group>
<start-time>2027-12-01T00:00:00+08:00</start-time>
<cron-expression>0 0/1 * * * ?</cron-expression>
</cron>
</trigger>
<!--该作业用于发送邮件-->
<job>
<name>SendMailJob</name>
<group>JobGroup1</group>
<description>发送邮件作业</description>
<job-type>TopshelfAndQuartz.SendMailJob,TopshelfAndQuartz</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>SendMailJobTrigger</name>
<group>SendMailJobTriggerGroup</group>
<job-name>SendMailJob</job-name>
<job-group>JobGroup1</job-group>
<start-time>2027-12-01T00:00:00+08:00</start-time>
<cron-expression>0 0/1 * * * ?</cron-expression>
</cron>
</trigger>
1) 可以发现,这里将作业分组名称都命名为“JobGroup1”,这是为了将这三个作业加入作业链中,需要将它们分为同一组中。
2) 另外,为了防止 SendSMSJob、SendMailJob 在服务启动后自动执行,将<start-time>节点设置成了2027-12-01T00:00:00+08:00,因为不希望它们自动执行。
2. 定义发送短信、发送邮件作业(这里只是简单打印执行日志)
/// <summary>
/// 发送短信作业。
/// </summary>
public class SendSMSJob : IJob
{
/// <summary>
/// 作业被触发时执行该方法。
/// </summary>
public void Execute(IJobExecutionContext context)
{
Log.Logger.Info("开始执行发送短信作业");
}
}
/// <summary>
/// 发送邮件作业。
/// </summary>
public class SendMailJob : IJob
{
/// <summary>
/// 作业被触发时执行该方法。
/// </summary>
public void Execute(IJobExecutionContext context)
{
Log.Logger.Info("开始执行发送邮件作业");
}
}
3. 配置作业监听程序
/// <summary>
/// 配置作业监听。
/// </summary>
public static void ConfigureJobListener()
{
ISchedulerFactory factory = new StdSchedulerFactory();
IScheduler scheduler = factory.GetScheduler();
JobChainingJobListener listener = null;
//创建作业Key(名称与分组)
JobKey uiJobKey = JobKey.Create("UpdateInventoryJob", "JobGroup1");
JobKey sendSmsJobKey = JobKey.Create("SendSMSJob", "JobGroup1");
JobKey sendMailJobKey = JobKey.Create("SendMailJob", "JobGroup1");
//设置作业监听链
listener = new JobChainingJobListener("链接更新库存、发送短信、发送邮件作业");
listener.AddJobChainLink(uiJobKey, sendSmsJobKey);
listener.AddJobChainLink(sendSmsJobKey, sendMailJobKey);
scheduler.ListenerManager.AddJobListener(listener,
GroupMatcher<JobKey>.GroupEquals("JobGroup1"));
}
4. 在服务运行前加入作业监听
Log.Logger.Info("服务开始运行");
ConfigureJobListener(); //配置作业监听
HostFactory.Run(o =>
{
//o.UseLog4Net(); //这里需要使用 log4net, Version=1.2.15.0 的版本,当前版本不兼容所以注释掉
o.Service<ServiceRunner>();
o.SetServiceName("TopshelfAndQuartzService");
o.SetDisplayName("库存更新服务");
o.SetDescription("该服务用于定时更新商品库存");
o.EnablePauseAndContinue();
});
5. 这样,我们作业监听链就配置好了,运行效果:
Ø 总结
1. 其实 Quartz.NET 的功能还是很强大,它支持多个作业或触发设置监听,并可以自定义作业监听(实现 IJobListener 接口)或触发器监听(实现 ITriggerListener 接口),有兴趣的朋友可以深入研究。
2. 可参考文章:
1) https://www.cnblogs.com/linzhao126/p/4528519.html
2) http://www.cnblogs.com/zhangzhi19861216/p/4756610.html
3) https://www.quartz-scheduler.net/documentation/index.html
使用 Quartz.NET 实现作业串行执行的更多相关文章
- spring定时器任务多任务串行执行问题排查
最近发现个生产问题,定时器任务某些任务没有及时执行.经过研究排查发现spring 定时器任务scheduled-tasks默认配置是单线程串行执行的,这就造成了若某个任务执行时间过长,其他任务一直在排 ...
- 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)
[源码下载] 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知) 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 ...
- oracle中并行执行不一定比串行执行快
并行执行与串行执行相比,能否缩短执行时间,取决于如下几个方面:1.待执行的目标SQL是否适合并行执行,有些SQL是不太适合并行执行的,比如走索引的嵌套循环连接.2.数据库服务器上的硬件资源(如CPU. ...
- NodeJs使用async让代码按顺序串行执行
描述 由于nodejs中的函数调用都是异步执行的,而笔者在工程开发中函数A需要四五个参数,而这四五个参数值都是通过函数调用获得,因此按顺序写代码时,执行到函数A时,往往函数A需要的参数值因为参数的异步 ...
- jenkins 多任务串行执行
摘要 今天在新创建自动化部署项目的时候遇到了一个问题:我们的项目是maven聚合的所以在构建maven项目的时候要从parent开始build,但是这样会造成一个问题,我每次添加此parent项目下的 ...
- loadrunner多场景的串行执行以及定时执行
方法一: 既然是脚本串行执行,那在场景设计中必然是要用多个脚本,要注意的是需要将Scenario Schedule中的Schedule by设置为Group的模式.然后按实际需要依次设置每个脚本的Sc ...
- SpringBoot中定时任务默认是串行执行 如何设置并行
SpringBoot项目中,定时任务默认是串行执行的,不论启动多少任务,都是一个执行完成,再执行下一个. 如何设置并行呢? @EnableAsync 和@Async 这两个注解来实现 ,具体如下: ...
- 任意promise串行执行算法 - 童彪
// 任意promise串行执行算法 - 童彪 function runAllPromise() { var p1 = new Promise((resove, reject) => { s ...
- 【Nodejs】nimble或async并不能保证程序串行执行,回调是回避不了的坑
先看一段例程: //------------------------------- // 用于创建目录 //------------------------------- function creat ...
随机推荐
- html图像、绝对路径和相对路径,链接
html图像 <img>标签可以在网页上插入一张图片,它是独立使用的标签,通过"src"属性定义图片的地址,通过"alt"属性定义图片加载失败时显示 ...
- BZOJ3456 城市规划 【多项式求ln】
题目链接 BZOJ3456 题解 真是一道经典好题,至此已经写了分治\(NTT\),多项式求逆,多项式求\(ln\)三种写法 我们发现我们要求的是大小为\(n\)无向联通图的数量 而\(n\)个点的无 ...
- java thread 线程40个问题汇总
http://www.codeceo.com/article/40-java-thread-problems.html 1.多线程有什么用? 一个可能在很多人看来很扯淡的一个问题:我会用多线程就好了, ...
- [luogu3388][割点]
题目链接 思路 真板子题.割点是指在一个无向图中,删去之后图将不再连通的点.可以用tarjan算法求.根据割点有两种情况,一种是根,一种是非根.如果不是根的就去判断在tarjan的时候当前节点所能到的 ...
- JDK和CGLIB动态代理区别
背景:虽然自己了解这两种代理的区别,但是面试时候还是答的很模糊,需要好好总结. 前言JDK动态代理实现原理(jdk8):https://blog.csdn.net/yhl_jxy/article/de ...
- 系统API执行没效果,可以检查一下是否与 360安全卫士 有关?!
今天在写一个工具软件,使用到一个系统API: mouse_event() 代码如下: mouse_event(MOUSEEVENTF_ABSOLUTE | MOUSEEVENTF_MOVE, x2, ...
- javascript学习笔记二
1.js的string对象 **创建 String对象 *** var str = "abc"; **方法 和 属性(文档) *** 属性 length : 字符串的长度 ***方 ...
- CentOS 7 输入中文 & 安装搜狗输入法
1.CentOS 7 输入中文 安装时,若选择了中文,CentOS 7 自带中文输入法:汉语(Intelligent Pinyin). 设置方法: 应用程序 → 系统工具 → 设置 → 区域和语言 → ...
- iis8使用url2.0模块实现http跳转到https
第一步安装,url 2.0重写模块 点击右键选择>获取新的web平台组件 找到url 重写工具2.0并安装 找到相应网站,选择 >url重写 设定名称后 匹配URL用于路径匹配 通用 (. ...
- Luogu P3355 骑士共存问题
题目链接 \(Click\) \(Here\) 二分图最大独立集.对任意两个可以相互攻击的点,我们可以选其中一个.对于不会互相攻击的,可以全部选中.所以我们只需要求出最大匹配,根据定理,二分图最大独立 ...