任务调度及远端管理(基于Quartz.net)

这篇文章我们来了解一些项目中的一个很重要的功能:任务调度

可能有些同学还不了解这个,其实简单点说任务调度与数据库中的Job是很相似的东西

只不过是运行的物理位置与管理方式有点不一样,从功能上来说我觉得还是差不多的,

存储过程有很大的局限性,耦合性也太高,所以最好把系统的一些Job放在代码层,

于是就有了Quartz.net,我们本篇就是针对Quartz.net的二次开发

一、新建HelloJob

HelloJob.cs,示例Job,每次执行都输出msg变量中的信息

 1 using Common.Logging;
 2 using Quartz;
 3
 4 namespace Job.Items
 5 {
 6     public class HelloJob : IJob
 7     {
 8         public const string Message = "msg";
 9         private static readonly ILog log = LogManager.GetLogger(typeof(HelloJob));
10
11         public virtual void Execute(IJobExecutionContext context)
12         {
13             var jobKey = context.JobDetail.Key;
14             var message = context.JobDetail.JobDataMap.GetString(Message);
15             log.InfoFormat("HelloJob: msg: {0}", message);
16         }
17     }
18 }

HelloJobExample.cs,每5秒执行一次

 1         public class HelloJobExample
 2         {
 3             public virtual void Run()
 4             {
 5                 ISchedulerFactory sf = new StdSchedulerFactory();
 6                 IScheduler sched = sf.GetScheduler();
 7
 8                 IJobDetail job = JobBuilder.Create<HelloJob>()
 9                     .WithIdentity("job1", "group1")
10                     .Build();
11
12                 JobDataMap map = job.JobDataMap;
13                 map.Put("msg", "Your remotely added job has executed!");
14
15                 ITrigger trigger = TriggerBuilder.Create()
16                     .WithIdentity("trigger1", "group1")
17                     .ForJob(job.Key)
18                     .WithCronSchedule("/5 * * ? * *")
19                     .Build();
20
21                 sched.ScheduleJob(job, trigger);
22                 sched.Start();
23             }
24         }

好了,有效代码就那么多,我们来试试

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var example = new HelloJobExample();
 6             example.Run();
 7
 8             Console.ReadKey();
 9         }
10     }

貌似没什么问题,如愿地执行了。

但是我们想想,实际运行中执行任务的服务器一般都是独立出来的,那怎么去管理这些任务的开启、关闭及暂停呢?

肯定不能每次手动去操作,那太麻烦了。我们的希望是在应用中(系统管理后台)去管理这些任务。万幸Quartz.net足够强大,

他是支持远程操作的,没有太深入了解,不过看调用参数应该是通过TCP请求进行操作的,我们试试看

二、Job远程管理

2.1、新建Job.Items项目,把之前新建的HelloJob.cs放在其中

2.2、新建Job.Server项目

新建RemoteServer.cs

 1     public class RemoteServer : ILjrJob
 2     {
 3         public string Name
 4         {
 5             get { return GetType().Name; }
 6         }
 7
 8         public virtual void Run()
 9         {
10             ILog log = LogManager.GetLogger(typeof(RemoteServer));
11
12             NameValueCollection properties = new NameValueCollection();
13             properties["quartz.scheduler.instanceName"] = "RemoteServer";
14             properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
15             properties["quartz.threadPool.threadCount"] = "5";
16             properties["quartz.threadPool.threadPriority"] = "Normal";
17             properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
18             properties["quartz.scheduler.exporter.port"] = "555";
19             properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
20             properties["quartz.scheduler.exporter.channelType"] = "tcp";
21             properties["quartz.scheduler.exporter.channelName"] = "httpQuartz";
22             properties["quartz.scheduler.exporter.rejectRemoteRequests"] = "true";
23 24         }
25     }

2.3、新建控制器HelloJobController

 1     public class HelloJobController : Controller
 2     {
 3         public ActionResult Index()
 4         {
 5             try
 6             {
 7                 if (HelloJobHelper.Trigger != null)
 8                 {
 9                     ViewBag.JobKey = "remotelyAddedJob";
10                     ViewBag.State = HelloJobHelper.Scheduler.GetTriggerState(HelloJobHelper.Trigger.Key);
11                     ViewBag.StartTime = HelloJobHelper.Trigger.StartTimeUtc.ToString();
12                 }
13                 else
14                 {
15                     ViewBag.State = "获取Job执行状态失败";
16                 }
17             }
18             catch (Exception ex)
19             {
20                 ViewBag.State = "Job服务器连接失败";
21             }
22
23             return View();
24         }
25         public ActionResult Run()
26         {
27             HelloJobHelper.RunJob();
28
29             return RedirectToAction("Index", "HelloJob");
30         }
31         public ActionResult Pause()
32         {
33             HelloJobHelper.PauseJob();
34
35             return RedirectToAction("Index", "HelloJob");
36         }
37         public ActionResult Resume()
38         {
39             HelloJobHelper.ResumeJob();
40             return RedirectToAction("Index", "HelloJob");
41         }
42     }

2.4、新建HelloJobHelper

先配置连接远端任务服务器的参数,这个要和上面的RemoteServer.cs对应

1             properties["quartz.scheduler.proxy"] = "true";
2             properties["quartz.scheduler.proxy.address"] = "tcp://127.0.0.1:555/QuartzScheduler";

我们来看看开始操作,运行这个方法,任务服务器将自动开启这个Job

 1         public static void RunJob()
 2         {
 3             if (!scheduler.CheckExists(jobKey))
 4             {
 5                 IJobDetail job = JobBuilder.Create<HelloJob>()
 6                     .WithIdentity(jobKey)
 7                     .Build();
 8
 9                 JobDataMap map = job.JobDataMap;
10                 map.Put("msg", "Your remotely added job has executed!");
11
12                 ITrigger trigger = TriggerBuilder.Create()
13                     .WithIdentity(triggerKey)
14                     .ForJob(job.Key)
15                     .WithCronSchedule("/5 * * ? * *")
16                     .Build();
17
18                 scheduler.ScheduleJob(job, trigger);
19
20                 JobDetail = job;
21                 Trigger = trigger;
22             }
23         }

暂停比较简单

1         public static void PauseJob()
2         {
3             scheduler.PauseJob(jobKey);
4         }

2.5、View

 1 @{
 2     ViewBag.Title = "Index";
 3     Layout = "~/Views/Shared/_Bootstrap.cshtml";
 4 }
 5
 6 <!DOCTYPE html>
 7
 8 <html>
 9 <head>
10     <meta name="viewport" content="width=device-width" />
11     <title>Index</title>
12     <style>
13         .col-sm-offset-2 {
14         margin-left:20px;
15         }
16     </style>
17 </head>
18 <body>
19     <br />
20     @using (Html.BeginForm("Run", "HelloJob", null, FormMethod.Post, new { @id = "form1", @class = "form-horizontal", role = "form" }))
21     {
22         @Html.AntiForgeryToken()
23         <div class="form-group">
24             <div class="col-sm-offset-2 col-sm-10">
25                 <input type="hidden" name="Id" id="Id" />
26                 <button type="submit" class="btn btn-default">Run</button>
27             </div>
28         </div>
29     }
30
31     @using (Html.BeginForm("Pause", "HelloJob", null, FormMethod.Post, new { @id = "form2", @class = "form-horizontal", role = "form" }))
32     {
33         @Html.AntiForgeryToken()
34         <div class="form-group">
35             <div class="col-sm-offset-2 col-sm-10">
36                 <input type="hidden" name="Id" id="Id" />
37                 <button type="submit" class="btn btn-default">Pause</button>
38             </div>
39         </div>
40     }
41
42     @using (Html.BeginForm("Resume", "HelloJob", null, FormMethod.Post, new { @id = "form3", @class = "form-horizontal", role = "form" }))
43     {
44         @Html.AntiForgeryToken()
45         <div class="form-group">
46             <div class="col-sm-offset-2 col-sm-10">
47                 <input type="hidden" name="Id" id="Id" />
48                 <button type="submit" class="btn btn-default">Resume</button>
49             </div>
50         </div>
51     }
52
53     <br />
54     <div>
55         <ul>
56             <li>ViewBag.JobKey: @ViewBag.JobKey</li>
57             <li>ViewBag.State: @ViewBag.State</li>
58             <li>ViewBag.StartTime: @ViewBag.StartTime</li>
59             <li>ViewBag.ExecuteTimes: @ViewBag.ExecuteTimes</li>
60         </ul>
61     </div>
62
63
64 </body>
65 </html>

2.6 好了,我们先运行服务端,开起来就好了

2.7、运行Web

2.7.1 点击Run

2.7.2、点击Pause(暂停)

2.7.3、点击Resume(恢复)

2.8、最后看看项目代码层次,涉及3个:MVC、Job.Items、Job.Server

好了,基本的功能有了。这篇就到这里

时间: 2024-10-24 21:45:58

任务调度及远端管理(基于Quartz.net)的相关文章

任务调度之集群(基于Quartz.net)

上一篇我们完成了任务调度的持久化,传送门:任务调度之持久化(基于Quartz.net) 这篇我们来完成Quartz.net的一个比较优秀的功能,即集群:集群可以提高任务调度服务的容灾性, 当一个节点宕机后,其他节点会自动补上去,把超时的Job继续执行下去. 当然了,某个Job同一时刻只会运行在一个节点上,他们是通过数据库锁实现的. 1.集群依赖于数据表 之前2张我们介绍的都是运行在内存上的Job,而集群则一定需要依赖于Quartz.net本身的数据表结构才行 就是这个: enter_db_nam

基于 Quartz 开发企业级任务调度应用--转

Quartz 基本概念及原理 Quartz Scheduler 开源框架 Quartz 是 OpenSymphony 开源组织在任务调度领域的一个开源项目,完全基于 Java 实现.该项目于 2009 年被 Terracotta 收购,目前是 Terracotta 旗下的一个项目.读者可以到 http://www.quartz-scheduler.org/站点下载 Quartz 的发布版本及其源代码.笔者在产品开发中使用的是版本 1.8.4,因此本文内容基于该版本.本文不仅介绍如何应用 Quar

Quartz.NET总结(五)基于Quartz.net 的开源任务管理平台

前面总结了很多,关于Quartz.net 的文章,介绍了如何使用Quartz.net.不清楚的朋友,可以看我之前的系列文章,http://www.cnblogs.com/zhangweizhong/category/771057.html . 最近,又重新整理,开发出了一套基于Quartz.net 的任务管理平台.将Quartz.net 的任务调度,管理等功能统一整合,形成了一套比较完整的任务调度平台.主要是:任务调度服务,后台任务管理 等功能. github地址:https://github.

Java 基于quartz实现定时 之二(XML方式配置)

<!-- 在spring核心配置文件中进行如下配置 --> <!-- Spring基于quartz定时任务 --> <bean id="triggerByBeanTwo" class="cn.zr.pringmvctest.trigger.TriggerByBeanTwo"></bean> <!-- jobDetail --> <bean id="triggerByBeanTwoJob&qu

基于Quartz.NET构建自己的动态作业调度器

在日常的开发中,运行定时任务基本上已经是很普遍的需求了,可以通过windows服务+timer组件来实现,也可以使用第三方框架来集成,Quartz.NET就是一款从JAVA的Quartz移植过来的一个不错的作业调度组件,但是当我们把作业都写好,并部署完成的时候,管理成为了很麻烦的事情,因此我基于Quartz.NET,又简单做了一下封装,来实现作业动态管理. 首先作业动态管理包含以下几个核心点 应用程序动态加载器 作业管理(运行)池 动态启动/停止/卸载作业 Quzrtz.NET怎么用我这里就不再

基于Quartz实现简单的定时发送邮件

一.什么是Quartz Quartz 是一个轻量级任务调度框架,只需要做些简单的配置就可以使用:它可以支持持久化的任务存储,即使是任务中断或服务重启后,仍可以继续运行.Quartz既可以做为独立的应用提供服务,也可以和其他应用集成一起使用. 核心概念: 1.Job 表示一个工作,要执行的具体内容.此接口中只有一个方法 void execute(JobExecutionContext context) 2.JobDetail JobDetail表示一个具体的可执行的调度程序,Job是这个可执行程调

JobEngine 基于quartz.net 跨平台作业框架

github:https://github.com/zzhi/JobEngine 基于quartz.net 的跨平台作业框架 quartz.net(https://github.com/quartznet/quartznet/tree/features/netcore11) 也支持跨平台了 ,由于NuGet无法安装quartz-DotNetCore dll. 所以我直接把这个解决方案下载下来,删除一些无用的代码,在解决方案上直接创建项目JobServer, 通过添加引用的方式引用quartz-D

使用foreman 管理基于Procfile 的应用

foreman 是一个协议,我们可以用来方便的管理基于Procfile 文件定义的应用(测试环境会很方便,当然生产也可以使用) 我们可以用来快速的搭建一个服务的依赖系统,同时方便的进行管理,同时社区也有了多种语言的实现 几个方便的语言实现 golang 参考地址:https://github.com/mattn/goreman python 参考地址:https://github.com/nickstenning/honcho nodejs 参考地址:https://github.com/str

[更新] 基于Quartz.NET 的任务调度管理工具

更新列表: 任务参数可视化. 立即中断正在执行的任务. 每个任务独立的应用程序域 上一版参见: 基于Quqrtz.NET 做的任务调度管理工具 界面具体变化如下: 任务参数可视化 如上图所示, 在管理任务的界面上就可以知道这个任务需哪些参数/类型 及 参数的说明. 实现方式, 在 Job 上添加 特性 :  ParameterTypeAttribute 1 namespace JobA { 2 [ParameterType(typeof(Parameter))] 3 public class J