.netcore组装一个可配置的调用webapi的定期任务服务

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

大功告成!不容易啊!

猜你喜欢

转载自www.cnblogs.com/ihappycat/p/11795051.html