1.需求
- 可调用webapi
- 可通过配置文件配置任务
- 通过cron进行时间配置
- 任务执行情况通过日志记录
- 可封闭成windows服务
- 有跨平台部署的潜力
2.选型
- 跨平台 .netcore
- 定期任务 Quartz.net
- 调用webapi Restsharp
- 配置webapi sharpconfig
- 日志记录 NLog
- 封闭windows服务 Topshelf
3.类库版本
创建一个控制台程序,我使用的ide是vs2019,通过nuget进行安装以下类库
4.程序结构
5.这是一个基本框架后期可以根据需求扩展,话不多说,上代码。
- quartz_jobs.xml
里面配置了一个任务demojob19,每2秒执行一次。
<?xml version="1.0" encoding="utf-8" ?>
<job-scheduling-data xmlns="http://quartznet.sourceforge.net/JobSchedulingData"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="2.0">
<processing-directives>
<overwrite-existing-data>true</overwrite-existing-data>
</processing-directives>
<schedule>
<job>
<name>demojob19</name>
<group>groupa</group>
<description>demo</description>
<job-type>Quartz.Hello.HelloJob,Quartz.Hello</job-type>
<durable>true</durable>
<recover>false</recover>
</job>
<trigger>
<cron>
<name>demotrigger1</name>
<group>groupa</group>
<description>demo</description>
<job-name>demojob19</job-name>
<job-group>groupa</job-group>
<cron-expression>*/2 * * * * ?</cron-expression>
</cron>
</trigger>
</schedule>
</job-scheduling-data>
- QuartzServer.cs
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
using System.Threading.Tasks;
namespace Quartz.Hello
{
class QuartzServer
{
private IScheduler scheduler;
public QuartzServer()
{
//初始化相关配置
RunProgramRunExample().GetAwaiter().GetResult();
}
public void Start()
{
//启动服务
scheduler.Start();
}
public void Stop()
{
//关闭服务
scheduler.Shutdown();
}
private async Task RunProgramRunExample()
{
try
{
// Grab the Scheduler instance from the Factory
NameValueCollection props = new NameValueCollection
{
{ "quartz.serializer.type", "binary" },
{"quartz.plugin.xml.type","Quartz.Plugin.Xml.XMLSchedulingDataProcessorPlugin, Quartz.Plugins" },
{"quartz.plugin.xml.fileNames","quartz_jobs.xml" } //指定任务配置文件
};
StdSchedulerFactory factory = new StdSchedulerFactory(props);
scheduler = await factory.GetScheduler();
}
catch (SchedulerException se)
{
Console.WriteLine(se);
}
}
}
}
- Program.cs
using Quartz.Impl;
using System;
using System.Collections.Specialized;
using System.Threading.Tasks;
using Topshelf;
namespace Quartz.Hello
{
public class Program
{
private static void Main(string[] args)
{
HostFactory.Run(x =>
{
x.Service<QuartzServer>(s =>
{
s.ConstructUsing(name => new QuartzServer());
s.WhenStarted(tc => tc.Start());
s.WhenStopped(tc => tc.Stop());
});
x.RunAsLocalSystem();
x.SetDescription("QuartzNet任务调度服务,通过配置文件执行!");
x.SetDisplayName("QuartzJobShedule");
x.SetServiceName("Quartz任务调度框架");
});
}
}
public class HelloJob : IJob
{
public async Task Execute(IJobExecutionContext context)
{
var logger = NLog.LogManager.GetCurrentClassLogger();
string jobName = context.JobDetail.Key.Name;//获取本次job中的name.对应quartz_jobs.xml中job节点中的name属性
if(Helper.ExecuteRestApi(jobName))//调用远程webapi接口
{
logger.Info( jobName + "执行成功!");
}
else
{
logger.Info(jobName + "执行失败!");
}
logger.Info("hello nlog!"+jobName+"正在运行!");
await Console.Out.WriteLineAsync("Greetings from HelloJob!中国");
logger.Debug("这是一个调式!");
}
}
}
- Helper.cs
using RestSharp;
using SharpConfig;
using System;
using System.Collections.Generic;
using System.Text;
namespace Quartz.Hello
{
class Helper
{
public static bool ExecuteRestApi(string jobname)
{
var config = Configuration.LoadFromFile("sample.cfg");
var section = config[jobname];
string url = section["rootUrl"].StringValue;
string methed= section["methed"].StringValue;
var client = new RestClient(url) ;
var request = new RestRequest(jobname);
var response= client.Get(request);
switch (methed) {
case "post":
response = client.Post(request);
break;
}
var statusCode = response.StatusCode.ToString();
return _ = statusCode == "200" ? true : false;
}
}
}
- Jobs.ini
[demojob19]
# a job
rootUrl = http://localhost:6001/api/
methed = get
- NLog.config
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File" fileName="filelog.txt" />
<target name="logconsole" xsi:type="Console" />
</targets>
<rules>
<logger name="*" minlevel="Info" writeTo="logconsole" />
<logger name="*" minlevel="Debug" writeTo="logfile" />
</rules>
</nlog>
6.运行一下
dotnet Quartz.Hello.dll
7.利用TopShelf安装成windows服务的方法
#安装服务
Quartz.Hello.exe install
#启动服务
Quartz.Hello.exe start
#卸载服务
Quartz.Hello.exe uninstall
大功告成!不容易啊!