简介:Quartz.NET是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等。 Quartz.NET允许开发人员根据时间间隔(或天)来调度作业。本框架结合Topshelf开发,简单明快,并且在部署,调试也是很简单的。
一、系统结构
定时任务作为系统的必备部分,我想应该有一个优秀的框架来处理。但是遗憾的是,在我来到我们团队的时候并没有一个很好的方案,一般的处理就是写一个windows服务,来处理。但是在单个的项目中还是算好的,如果是有多个项目,多个团队呢,如何能够统一的进行统一的调度,协调处理呢?于是有了自己搭建一个任务调度的系统的想法。
整体的思路如下:通过Topshelf和Quartz.NET来做定时任务的调度方法,然后将需要通过定时处理的做成各自项目的接口,由调度中心进行调度执行。框架图是这个样子的:
1、配置中心负责配置需要执行的job的时间节点,job参数,启动选项等;
2、Topshelf宿主机作为job的容器,容纳各个job的执行,并根据配置中心的数据执行任务调度;
3、任务管理器实际上是一个初始化的job,其作用是作为管理者的角色执行job的增删改查;
4、通过配置和调度,执行job,在这里建议是将具体的job执行任务交给具体项目的接口处理,job只是作为定时的调度,调度结果的收集,告警工作。
二、系统预览
配置中心,用于配置各个job的具体信息:
系统中的第一个job(管理job),就是作为其他job的管理者,他会在每20秒执行一次查询,将变更的配置信息同步到其他job中。
在Cronin表达式菜单中,用于配置job执行的频率,我姑且认为你很懒,不记得如何配置他们的执行参数吧,这个菜单就会解决你这个重要的问题:
在选项卡中配置指定的执行周期,将自动计算cron表达式。
在日志分析中将记录job执行的日志,日志内容包含普通日志以及错误信息,便于排查问题和监控job执行状态:
Topshelf服务生成的是一个exe可执行程序,之所以方便是因为他可以作为单独的可执行程序双击运行,也可以安装为window服务,随着系统的启动而运行。
程序跑起来后,每隔一秒钟有输出,看到的效果如下:
作为系统服务安装也很简单,如下命令:
安装:TopshelfDemo.exe install
启动:TopshelfDemo.exe start
卸载:TopshelfDemo.exe uninstall
安装成功后,接下来,我们就可以看到服务里多了一个服务:
三、项目结构
以上看到了系统的预览,现在来看看项目的结构吧。
1、LibraServer是Topshelf程序,也就是整个调度发起者;
2、LibraServerCommon是一个需要的公共方法;
3、LibraTaskManagerBLL是在job处理中的逻辑部分;
4、LibraTaskManagerDAL是在job处理中的数据处类;
5、LibraTaskManagerWeb是作为配置中心的web站点;
6、LibraTaskModels是job中使用到的实体类;
7、LibraTaskSet是job集合,用于添加各种job,项目中提供了两个job,一个就是必备的管理job,一个就是发起http请求的job;
8、LibraTaskUtility是通过Quartz.NET进行封装的job处理帮助类,包括job启动,停止等操作。
其他几个没有介绍到的类是用于另外的一个功能,就是用于持续集成,在项目上线的时候执行远程的发布,部署功能,这里暂时不做介绍。
四、开发自己的job
如果希望添加job如何处理呢?一个方法就是在项目的LibraTaskSet的Jobs中添加自己的job类,来处理自己的job。以项目中的发起http的请求SendHttpRequestJob为例。需要实现IJob接口中的Execute方法,然后在配置中心中添加对应的配置。
1、实现IJob接口类中的Execute方法:
///
/// 发送http请求
///
[DisallowConcurrentExecution]
class SendHttpRequestJob : IJob
{
public void Execute(IJobExecutionContext context)
{
var logBll = new LogBll();
// 获取Task 基本信息及 Task 配置的其他参数,任务启动时会读取配置文件节点的值传递过来
TaskModel task = QuartzHelper.GetTaskDetail(context);
if (string.IsNullOrEmpty(task.TaskParam)) return;
try
{
var httpResponse = WebHttpHelper.HttpGet(task.TaskParam);
LogHelper.WriteLog(httpResponse);
logBll.WriteRunInfo(task.TaskName, task.TaskID.ToString(), httpResponse);
}
catch (Exception ex)
{
logBll.WriteErrorInfo(ErrorLevelModel.Exception, ex.Message, ex.StackTrace, task.TaskName);
}
}
}
2、在配置中心中添加对应的配置:
需要注意的是在程序集名称这里需要添加该job所在的dll名称,类名需要添加类的全路径,包括命名空间,类名。比如这里就是:LibraTaskSet.Jobs.SendHttpRequestJob
如果你不想接着在这个项目中添加代码怎么办呢?也是可以的。
还是一样的操作流程,你可以自己新建一个项目,编写一个类,只要实现IJob中的Execute方法即可,然后在配置中心配置你编写的dll以及类名,当然了,需要将你写的dll拷贝到Topshelf宿主机目录下了。
五、总结
Topshelf是创建Windows服务的另一种方法,是一个开源的跨平台的宿主服务框架,支持Windows和Mono,结合Quartz.NET使用就非常的方便了,这里只是抛砖引玉的做一个开源的项目。项目源码传送门,项目中需要包需要nuget重新下载引用即可。数据库使用的是MySQL,初始化sql文件见LibraTaskManagerWeb\App_Data\libraserverdb.sql 文件。欢迎留言专区讨论交流。
原文来自http://aivabc.com/Home/BlogDetail/35