作者:痛苦逝去你的样子 | 来源:互联网 | 2023-09-13 04:31
这篇文章我们来了解一些项目中的一个很重要的功能:任务调度可能有些同学还不了解这个,其实简单点说任务调度与数据库中的Job是很相似的东西只不过是运行的物理位置与管理方式
这篇文章我们来了解一些项目中的一个很重要的功能:任务调度
可能有些同学还不了解这个,其实简单点说任务调度与数据库中的Job是很相似的东西
只不过是运行的物理位置与管理方式有点不一样,从功能上来说我觉得还是差不多的,
存储过程有很大的局限性,耦合性也太高,所以最好把系统的一些Job放在代码层,
于是就有了Quartz.net,我们本篇就是针对Quartz.net的二次开发
一、新建HelloJob
HelloJob.cs,示例Job,每次执行都输出msg变量中的信息
using Common.Logging;
using Quartz;
namespace Job.Items
{
public class HelloJob : IJob
{
public const string Message = "msg";
private static readonly ILog log = LogManager.GetLogger(typeof(HelloJob));
public virtual void Execute(IJobExecutionContext context)
{
var jobKey = context.JobDetail.Key;
var message = context.JobDetail.JobDataMap.GetString(Message);
log.InfoFormat("HelloJob: msg: {0}", message);
}
}
}
HelloJobExample.cs,每5秒执行一次
public class HelloJobExample
{
public virtual void Run()
{
ISchedulerFactory sf = new StdSchedulerFactory();
IScheduler sched = sf.GetScheduler();
IJobDetail job = JobBuilder.Create HelloJob ()
.WithIdentity("job1", "group1")
.Build();
JobDataMap map = job.JobDataMap;
map.Put("msg", "Your remotely added job has executed!");
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity("trigger1", "group1")
.ForJob(job.Key)
.WithCronSchedule("/5 * * ? * *")
.Build();
sched.ScheduleJob(job, trigger);
sched.Start();
}
}
好了,有效代码就那么多,我们来试试
class Program
{
static void Main(string[] args)
{
var example = new HelloJobExample();
example.Run();
Console.ReadKey();
}
}
貌似没什么问题,如愿地执行了。
但是我们想想,实际运行中执行任务的服务器一般都是独立出来的,那怎么去管理这些任务的开启、关闭及暂停呢?
肯定不能每次手动去操作,那太麻烦了。我们的希望是在应用中(系统管理后台)去管理这些任务。万幸Quartz.net足够强大,
他是支持远程操作的,没有太深入了解,不过看调用参数应该是通过TCP请求进行操作的,我们试试看
二、Job远程管理
2.1、新建Job.Items项目,把之前新建的HelloJob.cs放在其中
2.2、新建Job.Server项目
新建RemoteServer.cs
public class RemoteServer : ILjrJob
{
public string Name
{
get { return GetType().Name; }
public virtual void Run()
{
ILog log = LogManager.GetLogger(typeof(RemoteServer));
NameValueCollection properties = new NameValueCollection();
properties["quartz.scheduler.instanceName"] = "RemoteServer";
properties["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz";
properties["quartz.threadPool.threadCount"] = "";
properties["quartz.threadPool.threadPriority"] = "Normal";
properties["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz";
properties["quartz.scheduler.exporter.port"] = "";
properties["quartz.scheduler.exporter.bindName"] = "QuartzScheduler";
properties["quartz.scheduler.exporter.channelType"] = "tcp";
properties["quartz.scheduler.exporter.channelName"] = "httpQuartz";
properties["quartz.scheduler.exporter.rejectRemoteRequests"] = "true";
}
}
2.3、新建控制器HelloJobController
public class HelloJobController : Controller
{
public ActionResult Index()
{
try
{
if (HelloJobHelper.Trigger != null)
{
ViewBag.JobKey = "remotelyAddedJob";
ViewBag.State = HelloJobHelper.Scheduler.GetTriggerState(HelloJobHelper.Trigger.Key);
ViewBag.StartTime = HelloJobHelper.Trigger.StartTimeUtc.ToString();
}
else
{
ViewBag.State = "获取Job执行状态失败";
}
}
catch (Exception ex)
{
ViewBag.State = "Job服务器连接失败";
return View();
}
public ActionResult Run()
{
HelloJobHelper.RunJob();
return RedirectToAction("Index", "HelloJob");
}
public ActionResult Pause()
{
HelloJobHelper.PauseJob();
return RedirectToAction("Index", "HelloJob");
}
public ActionResult Resume()
{
HelloJobHelper.ResumeJob();
return RedirectToAction("Index", "HelloJob");
}
}
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
public static void RunJob()
{
if (!scheduler.CheckExists(jobKey))
{
IJobDetail job = JobBuilder.Create HelloJob ()
.WithIdentity(jobKey)
.Build();
JobDataMap map = job.JobDataMap;
map.Put("msg", "Your remotely added job has executed!");
ITrigger trigger = TriggerBuilder.Create()
.WithIdentity(triggerKey)
.ForJob(job.Key)
.WithCronSchedule("/5 * * ? * *")
.Build();
scheduler.ScheduleJob(job, trigger);
JobDetail = job;
Trigger = trigger;
}
}
暂停比较简单
public static void PauseJob()
{
scheduler.PauseJob(jobKey);
}
2.5、View
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Bootstrap.cshtml";
!DOCTYPE html
html
head
meta name="viewport" cOntent=" /
title Index /title
style
.col-sm-offset-2 {
margin-left:20px;
}
/style
/head
body
br /
@using (Html.BeginForm("Run", "HelloJob", null, FormMethod.Post, new { @id = "form1", @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
div
div
input type="hidden" name="Id" id="Id" /
button type="submit" Run /button
/div
/div
@using (Html.BeginForm("Pause", "HelloJob", null, FormMethod.Post, new { @id = "form2", @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
div
div
input type="hidden" name="Id" id="Id" /
button type="submit" Pause /button
/div
/div
@using (Html.BeginForm("Resume", "HelloJob", null, FormMethod.Post, new { @id = "form3", @class = "form-horizontal", role = "form" }))
{
@Html.AntiForgeryToken()
div
div
input type="hidden" name="Id" id="Id" /
button type="submit" Resume /button
/div
/div
br /
div
ul
li ViewBag.JobKey: @ViewBag.JobKey /li
li ViewBag.State: @ViewBag.State /li
li ViewBag.StartTime: @ViewBag.StartTime /li
li ViewBag.ExecuteTimes: @ViewBag.ExecuteTimes /li
/ul
/div
/body
/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
好了,基本的功能有了。这篇就到这里