任务调度及远端管理(基于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 

转载于:https://www.cnblogs.com/MuNet/p/6688064.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/397080.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2015/12/15--Document对象

<html> <head> <script type "text/javascript"> //使用document.write()输出流写文本 document.write("hello,world!"); //使用document.write()输出流写HTML document.write("<h1>welcome to my world!</h1>")…

C# 子类实例化基类 基类使用不了子类的方法_C#高级编程面试考题

一、简答题1.简述C#中的所有访问修饰符及访问权限private(私有的)给类&#xff0c;及所有类成员使用所有类成员的默认访问修饰符可访问范围当前类自身public(公开的)给类&#xff0c;及所有类成员使用可访问范围当前类自身所有的子类同一程序集其他类通过实例化也可以访问其他程…

协程(Coroutine)与多线程,多进程

执行多个任务可以使用多线程或多进程。 多进程中&#xff0c;同一个变量&#xff0c;各自有一份拷贝存在于每个进程中&#xff0c;互不影响 多线程中&#xff0c;所有变量都由所有线程共享。而线程间的切换是系统进行调度&#xff0c;无法控制&#xff0c;所以可能 一个进程中的…

关于img 403 forbidden的一些思考

网页中经常需要显示图片给用户看&#xff0c;对网站本身来说有的图片是从本地图片服务器来的&#xff0c;但是一旦数量多了以后&#xff0c;磁盘空间又是一个问题。 所以有时就希望显示其他网站的Image&#xff0c;直接把其他网站的图片显示在我的网站上。但并不是所有的外网Im…

Leetcode: Kth Largest Element in an Array

Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element.For example, Given [3,2,1,5,6,4] and k 2, return 5.Note: You may assume k is always valid, 1 ≤ k ≤ arrays lengt…

python 循环赋值_Python打牢基础,从19个语法开始!

Python简单易学&#xff0c;但又博大精深。许多人号称精通Python&#xff0c;却不会写Pythonic的代码&#xff0c;对很多常用包的使用也并不熟悉。学海无涯&#xff0c;我们先来了解一些Python中最基本的内容。Python的特点解释型语言&#xff0c;无需编译即可运行提供了交互式…

uwp连接mysql数据库_在 UWP 应用中使用 SQLite 数据库

在 UWP 应用中使用 SQLite 数据库Use a SQLite database in a UWP app06/26/2020本文内容可以使用 SQLite 在用户设备上的轻量级数据库中存储和检索数据。You can use SQLite to store and retrieve data in a light-weight database on the users device. 本指南演示如何执行该…

12-事件委托(事件代理)

什么是事件委托 通俗的讲&#xff0c;事件就是onclick&#xff0c;onmouseover&#xff0c;onmouseout&#xff0c;等就是事件&#xff0c;委托呢&#xff0c;就是让别人来做&#xff0c;这个事件本来是加在某些元素上的&#xff0c;然而你却加到别人身上来做&#xff0c;完成这…

oracle 窗口函数 (keep)

看到很多人对于keep不理解&#xff0c;这里解释一下&#xff01;Returns the row ranked first using DENSE_RANK2种取值&#xff1a;DENSE_RANK FIRSTDENSE_RANK LAST在keep (DENSE_RANK first ORDER BY sl) 结果集中再取max、min的例子。SQL> select * from test;ID MC SL…

MySQL 的实时性能监控利器

操作系统及MySQL数据库的实时性能状态数据尤为重要&#xff0c;特别是在有性能抖动的时候&#xff0c;这些实时的性能数据可以快速帮助你定位系统或MySQL数据库的性能瓶颈&#xff0c;就像你在Linux系统上使用「top&#xff0c;sar&#xff0c;iostat」等命令工具一样&#xff…

设置linearlayout最大高度_技术案例 | 排烟口个数与挡烟垂壁高度的关系探讨

随着《建筑防烟排烟系统技术标准》( 以下简称新规范) 的正式实施&#xff0c;新规范对排烟系统的设计提出了完全不同的设计理念。根据新规范正文: 当建筑空间净高不大于6m时&#xff0c;每个防烟分区的排烟量应按不小于60m/(h㎡)计算且不小于15,000m/h( 走道不小于13,000m/h) &…

python安装requests第三方模块

2018-08-28 22:04:51 1 .下载到桌面后解压&#xff0c;放到python的目录下 --------------------------------------------------------------------------------------------------------------------------------------------------------- 2 . 在CMD输入以下 F:\>cd /d F…

mysql整站源码安装_MySQL入门01-MySQL源码安装

操作系统&#xff1a;CentOS 6.7MySQL版本&#xff1a;5.6.301.前期准备首先需要CMake&#xff0c;可以yum直接安装&#xff1a;yum install cmake也可以官网 https://cmake.org/ 下载源码编译。我这里选择了官网下载最新版本cmake-3.5.2.tar.gz。# tar -zxvf cmake-3.5.2.tar.…

集算器协助Java处理结构化文本之条件过滤

直接用Java实现文本文件中数据按条件过滤会有如下的麻烦: 1、文件不是数据库&#xff0c;不能用SQL访问。当过滤条件变化时需要改写代码。如果要实现象SQL那样灵活的条件过滤&#xff0c;则需要自己实现动态表达式解析和求值&#xff0c;编程工作量非常大。 2、文件太大时不能一…

python3动态加载模块的方法实现

2019独角兽企业重金招聘Python工程师标准>>> 需求 我们有时写了一个功能&#xff0c;需要不断地调整&#xff0c;但是已经在线上了&#xff0c;而且在执行任务&#xff0c; 这时要更新上去源文件&#xff0c;而不能结束掉当前进程,怎么办&#xff1f; 所以这时&…

python 浮点数最小值_PYTHON学习笔记(3)——基本数据类型

本次学习原内容均来自MOOC国家精品课程《Python程序语言设计》嵩天第一篇在问题——“今天python了吗&#xff1f;”中基本数据类型1、 整数&#xff08;1&#xff09;整数无限制 pow(x,y) 计算 &#xff08;2&#xff09;四种进制 2、 浮点数类型&#xff08;1&#xff09;取整…

2018.08.29 NOIP模拟 pmatrix(线性筛)

【问题描述】 根据哥德巴赫猜想&#xff08;每个不小于 6 的偶数都可以表示为两个奇素数之和&#xff09;&#xff0c;定义 哥德巴赫矩阵 A 如下&#xff1a;对于正整数对(i,j)&#xff0c;若 ij 为偶数且 i,j 均为奇素数&#xff0c;则 Ai,j 1&#xff0c; 否则 Ai,j 0。现…

Windows Azure移动终端云服务管理(公测版)

概览 云在远方&#xff0c;管理在您手中。在这个移动为先 云为先的世界&#xff0c;服务不再是基于请求才提供&#xff0c;而是主动来到身边方便您的模式了。我们最近将会陆续推出几大移动端利器帮助您随时随地管理您的云服务。 首批利器之中排名第一当属Azure云助手应用, 它是…

学习opencv3中文版_给视觉组新生的一点学习建议

如果说机械组是把机器人做出来电控组让机器人动起来那么视觉组就是让机器人智能化完成一个合格的机器人三者缺一不可今天就让我们来看看视觉组师兄推荐的学习建议吧&#xff01;1语言基础 野狼队视觉组目前使用的主要语言是C&#xff0c;同时也需要具备一定的C语言基础。建议…

如何动态改变audio的播放的src

如何动态改变audio的播放的src 一、总结 一句话总结&#xff1a;js方式在请求外部网站的时候行&#xff0c;php方式在请求内外部资源都行。因为php走在js前面&#xff0c;所以问题可以从php方面想办法。 1、如何使用js控制修改audio的src或它的source 的src属性实现动态改变aud…