码迷,mamicode.com
首页 > Web开发 > 详细

使用 Quartz.NET 实现作业串行运行

时间:2018-03-28 01:28:51      阅读:1260      评论:0      收藏:0      [点我收藏+]

标签:art   接口   bottom   分组   监听   normal   div   https   factor   

?  前言

前两天,在公司的一个项目中编写 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)   另外,为了防止 SendSMSJobSendMailJob 在服务启动后自动执行,将<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 实现作业串行运行

标签:art   接口   bottom   分组   监听   normal   div   https   factor   

原文地址:https://www.cnblogs.com/abeam/p/8661274.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!