任務調度及遠端管理(基於Quartz.net)

這篇文章咱們來了解一些項目中的一個很重要的功能:任務調度html

可能有些同窗還不瞭解這個,其實簡單點說任務調度與數據庫中的Job是很類似的東西數據庫

只不過是運行的物理位置與管理方式有點不同,從功能上來講我以爲仍是差很少的,服務器

存儲過程有很大的侷限性,耦合性也過高,因此最好把系統的一些Job放在代碼層,tcp

因而就有了Quartz.net,咱們本篇就是針對Quartz.net的二次開發ui

 

1、新建HelloJob

HelloJob.cs,示例Job,每次執行都輸出msg變量中的信息spa

 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秒執行一次.net

 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         }

好了,有效代碼就那麼多,咱們來試試code

 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     }

貌似沒什麼問題,如願地執行了。orm

 

可是咱們想一想,實際運行中執行任務的服務器通常都是獨立出來的,那怎麼去管理這些任務的開啓、關閉及暫停呢?htm

確定不能每次手動去操做,那太麻煩了。咱們的但願是在應用中(系統管理後臺)去管理這些任務。萬幸Quartz.net足夠強大,

他是支持遠程操做的,沒有太深刻了解,不過看調用參數應該是經過TCP請求進行操做的,咱們試試看

 

2、Job遠程管理

2.一、新建Job.Items項目,把以前新建的HelloJob.cs放在其中

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.三、新建控制器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.四、新建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.五、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.七、運行Web

2.7.1 點擊Run

2.7.二、點擊Pause(暫停)

2.7.三、點擊Resume(恢復)

 

2.八、最後看看項目代碼層次,涉及3個:MVC、Job.Items、Job.Server

 

好了,基本的功能有了。這篇就到這裏

相關文章
相關標籤/搜索