使用ASP.NET页面管理的定时作业Web调度器






4.76/5 (11投票s)
通过ASP.NET管理页面安排定时任务。
引言
本文介绍了一个基于Web的作业调度器,您可以在其中添加和管理日常或每月的管理或报告发送任务。有其他一些方法可以实现此目的,但我发现没有一种完全令人满意,因此我决定编写自己的作业调度器。一方面,您可以使用Windows任务计划程序运行一些脚本,另一方面,您可以使用MS SQL Server Agent作业调度程序执行一些存储过程来处理数据库维护作业。本项目旨在结合这两种方法,使它们可以通过易于管理的ASP.NET页面进行处理。
特点
- 每日和每周作业(计划将来改进此功能)
- 两种作业步骤:运行脚本,运行存储过程
- 对于一个作业,您可以添加多个步骤
- 启用/禁用作业
- 立即运行作业
背景
本项目的主要目标是发送每周报告,并将需要某种方式自动化的作业集中起来,例如备份作业和其他数据库维护任务。我不想改动Windows任务计划程序或MS SQL Server中的作业计划程序,因此我决定创建自己的调度程序,该调度程序具有清晰的管理页面,可以轻松管理作业。
使用代码
该项目有两个主要部分
- MS SQL Server数据库(文件:JOBS_db.zip):包含一些表和一些存储过程。基本上,这是系统的框架。它存储您的任务和其他相关信息的数据。此外,还有管理作业的存储过程。例如:插入,编辑和删除作业或作业步骤。然后通过.NET应用程序调用这些过程。
- Visual Studio项目(文件:jobs.zip):此解决方案包含项目的管理页面。它包含一些SQL执行例程,这些例程在插入,编辑或删除作业或作业步骤时触发。它提供了任务的清晰概述以及一些额外功能,例如启用/禁用或立即运行作业。
这是JOBS数据库的结构
程序逻辑
关于此项目的核心问题是如何在不启动浏览器或其他任何东西的情况下,在计划的时间在后台执行作业。答案非常简单:您只需在SQL Server Agent中创建一个作业,该作业每天每10秒运行一次,例如。它就像一个无限循环,仅此而已;它只是启动一个存储过程,该存储过程执行并处理存储在JOBS表中的任务。这样,您所有预定义的作业都可以根据需要静默地在后台执行。需要放置在循环作业中的存储过程称为begin_jobs(也包含在zip文件中)。它为JOBS表创建一个CURSOR
,遍历必须在正确时间执行的作业记录,然后逐个步骤执行它们。
CREATE PROCEDURE [dbo].[begin_jobs]
AS
BEGIN
SET NOCOUNT ON;
DECLARE @job_id int
DECLARE jobCursor CURSOR FOR
SELECT id
FROM JOBS
WHERE [enabled] = 1 AND
valid = 1 AND
job_is_running = 0 AND
next_run <= GETDATE()
OPEN jobCursor
FETCH FROM jobCursor INTO @job_id
WHILE (@@FETCH_STATUS = 0)
BEGIN
EXEC [dbo].[execute_job] @job_id
FETCH FROM jobCursor INTO @job_id
END
CLOSE jobCursor
DEALLOCATE jobCursor
END
一旦数据库结构构建完成,我们将需要更多存储过程来管理我们的作业。以下示例将完整描述通过ASP.NET页面插入作业的过程。将新行插入JOBS表的存储过程如下:
CREATE PROCEDURE [dbo].[insert_job]
@scheduler_type varchar(1024),
@description varchar(1024),
@monday bit,
@tuesday bit,
@wednesday bit,
@thursday bit,
@friday bit,
@saturday bit,
@sunday bit,
@occurs_at datetime
AS
BEGIN
SET NOCOUNT ON;
DECLARE @schedule_type_id int,
@job_id int
SET @schedule_type_id = (SELECT TOP 1 id
FROM SCHEDULE_TYPES
WHERE UPPER([description]) = UPPER(@schedule_type))
IF @description = '' OR @description IS NULL OR @schedule_type_id IS NULL
RETURN
INSERT INTO JOBS (schedule_type_id, [description])
VALUES (@schedule_type_id, @description)
SET @job_id = (SELECT @@IDENTITY)
INSERT INTO SCHEDULES (job_id, monday, tuesday, wednesday,
thursday, friday, saturday, sunday, occurs_at)
VALUES (@job_id, @monday, @tuesday, @wednesday, @thursday,
@friday, @saturday, @sunday, @occurs_at)
-- UPDATE next_run
EXEC [dbo].[update_next_run] @job_id
-- UPDATE schedule_description
EXEC [dbo].[update_schedule_description] @job_id
END
ASP.NET应用程序将在单击“创建作业”按钮时调用上述过程,如下所示:
using System.Data;
using System.Data.SqlClient;
using HelperLib;
private string connStringJobs = ConfigurationManager.ConnectionStrings["jobs"].ToString();
protected void btnCreate_Click(object sender, EventArgs e)
{
//...some security checks
SqlHelper mySqlHelper = new SqlHelper(connStringJobs,
CommandType.StoredProcedure, "insert_job",
new SqlParameter("@schedule_type", dropListScheduleTypes.SelectedItem.Text),
new SqlParameter("@description", txtDescription.Text),
new SqlParameter("@monday", monday),
new SqlParameter("@tuesday", tuesday),
new SqlParameter("@wednesday", wednesday),
new SqlParameter("@thursday", thursday),
new SqlParameter("@friday", friday),
new SqlParameter("@saturday" saturday),
new SqlParameter("@sunday", sunday),
new SqlParameter("@occurs_at", occurs_at));
mySqlHelper.ExecuteNonQuery();
mySqlHelper.Close();
Response.Redirect("Default.aspx");
}
connStringJobs
变量的值来自web.config文件
<add name="jobs"
connectionString="server=xxx;database=JOBS;UID=userreader;PWD=nopass"
providerName="System.Data.SqlClient"/>
它有一个硬编码的用户名和密码,还需要在SQL Server中创建为数据库用户登录。我的建议是授予它管理员权限,因为该用户将执行JOB表中的所有作业。这不是最佳的安全方法,但如果您还计划在自己的任务中运行脚本,那么在不授予该用户管理员权限的情况下运行外部脚本时,可能会遇到一些权限问题。如果您只运行存储过程,那么在包括JOBS数据库在内的相关数据库上,执行权限应该足够。在JOBS数据库上必须具有执行权限。
SqlHelper
类也应该进行解释,因为它不是标准的C#类。它是我的SQL工具集合。它简化了SQL Server的连接,并提供了许多其他有用的函数和方法,可以缩短编码。如果有人需要它的源代码,请告诉我。
安装
- 将JOBS.bak(JOBS_db.zip)数据库恢复到您的SQL Server数据库。您可以使用Microsoft SQL Server Management Studio还原向导进行此操作。右键单击“数据库”,然后单击“还原数据库...”。然后按照屏幕上的说明进行操作。成功还原数据库后,您将在JOBS数据库中看到前面提到的表和存储过程,您还将在其中找到一些可以在管理页面稍后删除的示例任务。
- 在JOBS数据库中创建一个数据库用户登录,并授予其管理员权限。将其命名为userreader,密码为nopass。
- 使用Visual Studio打开jobs.sln(jobs.zip)解决方案,并修改web.config文件中的两个连接字符串以满足您的需求,然后将其发布到您的站点。
- 打开浏览器并导航到您刚刚发布的jobs管理页面,然后开始创建和管理您自己的作业。
- 在Microsoft SQL Server Management Studio中创建一个作业,该作业仅包含一个步骤,该步骤运行以下存储过程:[JOBS].[dbo].[begin_jobs],并为此作业创建一个计划,该计划每天每10秒发生一次。