请读者稍等,设计图,以及代码,随后会给出。


需求文档如下:


1 引言

  1. 1.1背景

本次开发系统的名称为:任务调度系统,设计开发人员:Van,本系统用户:需要任务调度的开发团队或单位。由于业务的不断变化和更新,而导致数据库的脚本变的越来越庞大、越来越复杂,脚本执行的时间越来越长,效率越来越低,为了给用户提供良好的使用体验,将业务进行整理,实现批量操作等多种方式来提高效率。目前将原来的DB job过程封装到业务DLL中,即业务插件。由于业务插件比较多,而且执行的方式也不尽相同,所以在这样的情况下,需要实现类似DB job的调度系统。考虑到系统的可控性,扩展性,易维护性决定启动本项目来开发相应的系统。

 

1.2 环境配置

    以下硬件要求为,系统运行的最低要求,为保证系统能够稳定、高效的运行,建议尽量提高系统硬件的配置。

 

支持的操作系统

Windows 7, Windows 7Service Pack 1, Windows Server 2003 Service Pack 2, Windows Server 2008,Windows Server 2008 R2, Windows Server 2008 R2 SP1, Windows Vista Service Pack1, Windows XP Service Pack 3

·        Windows XP SP3

·        Windows Server 2003 SP2

·        Windows Vista SP1 或更高版本

·        Windows Server 2008(在服务器核心角色上不受支持)

·        Windows 7

·        Windows Server 2008 R2(在服务器核心角色上不受支持)

·        Windows 7 SP1

·        Windows Server 2008 R2 SP1

·        支持的体系结构:

·        x86

·        x64

·        ia64(有些功能在诸如 WPF 之类的 ia64 上不受支持)

·        硬件要求:

·        建议的最低要求:Pentium 1 GHz 或更快,512 MB RAM 或更大

·        最小磁盘空间:

·        x86 – 850 MB

·        x64 – 2 GB

·        必备组件:

·        Windows Installer 3.1 或更高版本

·        Internet Explorer 5.01 或更高版本

·        Microsoft .NET Framework 4.0或更高版本

 

1.3 参考资料

MSDN官方网站

其他网络资料

 

2. 功能需求

2.1 系统范围

   本系统的目标是对特定的任务进行调度,系统要求具有非常高的稳定性,一次启动需要长期运行;系统要求具有非常高的容错性,单个任务发生错误,取消,异常等可控或者不可控的问题,必须不能影响系统的正常运行。系统调度的任务必须以可执行文件或者动态链接库文件的形式提供,动态链接库必须实现特定接口,必须用特定语言编译而成。任务可以动态增加或者取消,任务的增加和取消需要在一定时间内自动起效,不需要重启服务或者其他额外操作。系统需要提供明确的任务配置方式。

 

2.2 系统总体设计

   本系统最终交付结果为windows服务程序文件夹,windows服务启动程序,插件任务配置XML文件,插件任务配置及使用说明文件。

   主要模块划分如下:

    <1> 配置文件加载模块:负责加载配置文件,并提供相关的任务对象。

    <2> 配置文件监控模块:负责动态更新任务列表。

    <3> 任务接口模块:定义业务插件的调用接口以及相关对象。

<4> 动态链接库插件执行模块:负责动态链接库形式插件的执行。

    <5> 任务管理调度模块:负责定时检查任务是否执行,并发送相应的调度指令。

    <6> 任务命令执行模块:负责执行具体的任务指令。

    <7> 任务检查模块:根据具体任务参数配置,判断任务是否需要执行。

<8> 日志记录模块:包括异常日志,调度日志,执行日志,系统日志(包括服务启动和任务增删改的信息)。

 

稳定性和容错性设计:

为了保证系统的稳定,防止一个任务发生错误、崩溃、或者异常而导致整个系统崩溃的情况,系统设计采取进程隔离的策略,将每一个任务在一个单独的进程中运行。这样每一个任务进程的相关信息,可以设置成与任务相关的内容,方便维护人员及时发现并清除异常任务,而不影响其他任务的执行。

 

2.3 需求分析

2.3.1 任务信息配置

任务信息可配置内容如下(未特殊说明该项可以不配):

<1> 名称(必须配置,且必须唯一)

<2> 可执行文件路径(必须配置,如果用户未提供,则请拷贝系统默认文件并重命名)

<3> 业务插件路径(如果上述可执行文件为用户指定,该项可以不配,否则必须配置)

<4> 开始时间(未配置该项,则由系统自动调度)

<5> 结束时间(未配置该项,则以永久运行处理)

<6> 创建时间

<7> 创建用户

<8> 任务说明(建议配置,描述任务的相关功能和注意事项)

<9> 日志记录方式配置

 

配置文件模板如下( TaskManageConfig.xml ):

 

<?xmlversion="1.0"encoding="utf-8" ?>

<!--errorlogtype:file,db; other: no-->

<TaskListerrorlogtype="file,db">

  <taskname="TaskExample"exepath="plugs\\Demo.exe"dllpath="plugs\\TaskDemo.dll"

        begintime="2014-09-11 17:00:00"endtime="2015-09-11 23:00:00"createtime="2014-09-1017:00:00"createuser="van.x.yang">

    <!--type:daily,weekly,monthly;days:[1-n]or[1-7]or[1-31];running:cancel,continue;-->

   <!--maxprocesscount:[1-n];isclosewhentimeout:true,false-->

   <schedules type="monthly" days="1,3,15,27"running="cancel" maxprocesscount="100"isclosewhentimeout="false"emailwhenfailure="Van.X.Yang@newegg.com">

     <!--type:onetime,loop,loopwait;unit:h(hour),m(minute),s(second),ms(millisecond)-->

     <schedule type="onetime" starttime="07:00:00"timeout="" unit="m"></schedule>

     <schedule type="onetime" starttime="09:00:00"timeout="" unit="m"></schedule>

     <schedule type="loop" interval="30"timeout="" unit="m" starttime="10:00:00"endtime="17:00:00" />

     <schedule type="loopwait" interval="2"timeout="" unit="s" starttime="01:00:00"endtime="06:00:00" />

   </schedules>

    <!--schedulelogtype and executelogtype:file,db; other: no-->

    <logsetschedulelogtype="file,db"executelogtype="file,db"/>

    <description><![CDATA[Task plugin example.]]></description>

  </task>

</TaskList>

 

说明如下:

1) Name:任务名称,字符串类型,建议输入英文字符。

2) exepath:可执行文件相对路径,以plugs文件夹为根目录,来设置具体目录。

2) dllpath:任务插件相对路径,以plugs文件夹为根目录,来设置插件目录。

3) begintime:任务开始时间,时间类型,必须符合时间格式和要求,即:年-月-日 时:分:秒,约定:年为4位,月、日、时、分、秒均为2位。

4) endtime:任务结束时间,要求同上。

5) createtime:任务创建时间,要求同上。

6) createuser:创建用户,任务创建人。

7) description:任务描述信息。

8) errorlogtype:系统异常输出形式,目前支持文件和数据库。

9) schedulelogtype:调度日志输出形式,目前支持文件和数据库。

10) executelogtype:执行日志输出形式,目前支持文件和数据库。

 

说明:针对8,9,10,如果配置一个则写一个,配置两个则写两个,如果为空,则不输出日志(该3项对异常日志,调度日志,执行日志有效,system.log则始终记录)

 

2.3.2 任务调度方式配置(不同任务之间彼此独立,互不干扰,以下说明均指同一个任务

 

配置文件模板如下:

 

<?xml version="1.0"encoding="utf-8" ?>

<!--errorlogtype:file,db; other:no-->

<TaskListerrorlogtype="file,db">

 <task name="TaskExample"exepath="plugs\\Demo.exe" dllpath="plugs\\TaskDemo.dll"

       begintime="2014-09-11 17:00:00" endtime="2015-09-1123:00:00" createtime="2014-09-10 17:00:00"createuser="van.x.yang">

   <!--type:daily,weekly,monthly;days:[1-n]or[1-7]or[1-31];running:cancel,continue;-->

    <!--maxprocesscount:[1-n];isclosewhentimeout:true,false-->

    <schedulestype="monthly"days="1,3,15,27"running="cancel"maxprocesscount="100"isclosewhentimeout="false"emailwhenfailure="Van.X.Yang@newegg.com">

      <!--type:onetime,loop,loopwait;unit:h(hour),m(minute),s(second),ms(millisecond)-->

      <scheduletype="onetime"starttime="07:00:00"timeout=""unit="m"></schedule>

      <scheduletype="onetime"starttime="09:00:00"timeout=""unit="m"></schedule>

      <scheduletype="loop"interval="30"timeout=""unit="m"starttime="10:00:00"endtime="17:00:00" />

      <scheduletype="loopwait"interval="2"timeout=""unit="s"starttime="01:00:00"endtime="06:00:00" />

    </schedules>

    <!--schedulelogtype and executelogtype:file,db;other: no-->

   <logset schedulelogtype="file,db"executelogtype="file,db"/>

   <description><![CDATA[Task pluginexample.]]></description>

 </task>

</TaskList>

 

说明如下:

 

<1> 思路为:通过schedules节点的type、days属性,定位到具体需要调度的某一天;然后通过schedule节点来定义具体的调度形式。

 

<2> running: 如果上次调度任务正在运行,是取消本次调度还是继续本次调度。Cancel为取消本次调度,continue为继续本次调度。

 

<3> maxprocesscount: 当任务可以并发执行时,表示该任务允许同时启动的最大进程数。请根据服务器的性能合理配置该参数。

 

<4> isclosewhentimeout: 当任务超时的时候,系统是否需要终止该任务。

 

<5> emailwhenfailure: 当任务执行失败或者超时后,系统发送通知邮件的邮件地址,如果该地址为空则不发送邮件。如果向多个人发送,则邮件中间用分号隔开。

 

<6> schedules::type和schedules::days属性取值必须匹配,取值说明如下:

 

daily

表示按天调度,则days的取值含义为,每几天调度一次,例如:1为每一天调度一次,2为每2天调度一次,所以调度间隔的天数为:days-1。取值范围为: 大于等于1的整数。

 

Weekly

表示按周调度,则days的取值含义为,每周的哪几个星期,取值范围为:大于等于1且小于等于7的整数,多个值用英文输入法的逗号分隔。

 

Monthly:

表示按月调度,则days的取值含义为,每月的哪几天,理论取值范围为:大于等于1且小于等于31的整数,多个值用英文输入法的逗号分隔。注意:如果该月份的这一天不存在时,则会忽略本次调度。

 

<6> schedule::type的取值目前定义了三种情况,取值说明如下:

 

注意:以下三种情况的说明,均针对某一特定天而言!天的确定方式,请参考上一条款。

 

timeout: 表示该任务的预设超时时间。

unit: 表示时间单位,具体支持情况请参考注释。

 

onetime:表示仅调度一次,starttime:表示调度的开始时间。

loop:表示固定时间间隔调度任务,interval:表示间隔时间,unit:表示时间单位,starttime:表示开始时间,endtime:表示结束时间。

loopwait:表示任务完成后等待一段时间后再次调度任务,interval:表示等待时间,unit:表示时间单位,starttime:表示开始时间,endtime:表示结束时间。

 

2.3.3 系统配置

系统配置文件模板如下(SystemInfoConfig.xml):

 

<?xmlversion="1.0"encoding="utf-8" ?>

<systeminfo>

  <serviceinfo>

    <servicename>IM_TaskScheduleService</servicename>

    <displayname>IM_TaskScheduleService</displayname>

    <description><![CDATA[IM Task Schedule Service]]></description>

  </serviceinfo>

  <!--time unit: millisecond-->

  <checktimeinterval>

    <schedule>10</schedule>

    <tasktimeout>2000</tasktimeout>

    <taskconfigfile>2000</taskconfigfile>

    <logoutput>10000</logoutput>

  </checktimeinterval>

  <erroremail>

    <frommail>IM_TaskScheduleService@ErrorMessage.com</frommail>

    <receivermail>Van.X.Yang@newegg.com</receivermail>

    <mailsubject>(info) error message</mailsubject>

    <sendemailexe>program\\email\\SendEmailExe.exe</sendemailexe>

  </erroremail>

  <connectionstring>

    Data Source=.\SQLEXPRESS;InitialCatalog=IM_TaskSchedule_LogRecord;Integrated Security=True

  </connectionstring>

  <logcommands>

    <errorlogcommand>

      <![CDATA[INSERT INTO [IM_TaskSchedule_ExceptionLog]

                          (

                               [Time]

                              ,[Type]

                              ,[ErrorMessage]

                              ,[ExceptionInfo]

                          )

                          VALUES

                          (

                               '{0}'

                              ,'{1}'

                              ,'{2}'

                              ,'{3}'

                          )]]>

    </errorlogcommand>

    <schedulelogcommand>

      <![CDATA[INSERT INTO [IM_TaskSchedule_ScheduleLog]

                          (

                               [Time]

                              ,[Taskname]

                              ,[ScheduleInfo]

                              ,[State]

                          )

                          VALUES

                          (

                                 '{0}'

                                ,'{1}'

                                ,'{2}'

                                ,'{3}'

                          )]]>

    </schedulelogcommand>

    <executelogcommand>

      <![CDATA[INSERT INTO [IM_TaskSchedule_ExecuteLog]

                          (

                               [Taskname]

                              ,[BeginTime]

                              ,[EndTime]

                              ,[State]

                              ,[ExceptionInfo]

                          )

                          VALUES

                          (

                               '{0}'

                              ,'{1}'

                              ,'{2}'

                              ,'{3}'

                              ,'{4}'

                          )]]>

    </executelogcommand>

  </logcommands>

</systeminfo>

 

说明:

<1> serviceinfo节点

servicename: 任务调度服务的名称。

displayname: 任务调度服务显示名称。

description: 任务调度服务说明信息。

 

<2> checktimeinterval节点

schedule: 表示系统调度的检测时间间隔。

tasktimeout: 表示任务超时的检测时间间隔。

taskconfigfile: 表示任务配置文件的检测时间间隔。

logoutput: 表示系统日志输出的检测时间间隔(包括系统异常日志,调度日志,执行日志)。

 

<3> erroremail节点

frommail:发件人地址。

receivermail:收件人地址。

mailsubject: 邮件主题。

sendemailexe: 邮件发送程序相对路径(系统参数,请慎重修改)。

注意:

<3.1> 如果不希望系统发送错误邮件,则将receivermail的内容配置为空。其他节点的值请慎重修改,当任务执行失败或者超时后,在发送任务执行邮件时会用到该节点的信息。

<3.2> 如果向多个人发送,则收件人邮件中间用分号隔开。

 

<4> connectionstring节点

connectionstring : 数据库连接字符串(当配置有写数据库日志时使用)。

 

<5> logcommands节点

errorlogcommand : 异常日志插入的SQL语句。

schedulelogcommand : 调度日志插入的SQL语句。

executelogcommand : 执行日志插入的SQL语句。

 

3 非功能性需求

3.1 性能和变化要求

整个系统必须要稳定、高效、容错、可扩展。

 

3.2 精度要求

考虑到实际的应用,目前各个时间都精确到秒,如果不能满足要求,在确定具体精度。

 

3.3 输出要求

必须记录详细的日志,让用户可以知道每一个任务,每一次执行的具体情况。

 

4 其他需求

待发现。

 

                                                                        Van.X.Yang