You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
698 lines
21 KiB
698 lines
21 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Reflection;
|
|
using System.ServiceModel;
|
|
using Topshelf;
|
|
using Quartz;
|
|
using Quartz.Impl;
|
|
using System.Threading;
|
|
|
|
namespace QMTask.Core
|
|
{
|
|
/// <summary>
|
|
/// 调度管理器
|
|
/// </summary>
|
|
public class TaskServer : ServiceControl
|
|
{
|
|
#region 成员变量
|
|
|
|
//任务列表
|
|
private List<TaskInfo> _tasks { get; set; }
|
|
|
|
//计划列表
|
|
private Dictionary<JobKey, PlanInfo> _plans { get; set; }
|
|
|
|
//任务工厂
|
|
private ISchedulerFactory _sfactory = new StdSchedulerFactory();
|
|
private IScheduler _sched = null;
|
|
|
|
//发布服务宿主
|
|
private ServiceHost PublishHost = new ServiceHost(typeof(TaskService));
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// 输出日志委托
|
|
/// </summary>
|
|
/// <param name="sender">所属容器</param>
|
|
/// <param name="sql">sql语句</param>
|
|
/// <param name="parameters">参数</param>
|
|
public delegate void ExportMonitorEventHandler(object sender, MonitorInfo arg);
|
|
|
|
/// <summary>
|
|
/// 输出日志事件
|
|
/// </summary>
|
|
public event ExportMonitorEventHandler ExportMonitorEvent = null;
|
|
|
|
#region 属性
|
|
|
|
//监控信息
|
|
public Dictionary<JobKey, MonitorInfo> MonitorInfos { get; set; }
|
|
|
|
/// <summary>
|
|
/// 运行状态
|
|
/// </summary>
|
|
public bool Running { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region 服务控制
|
|
|
|
public bool StartService()
|
|
{
|
|
try
|
|
{
|
|
//启动远程服务
|
|
if (PublishHost.State != CommunicationState.Opening)
|
|
PublishHost.Open();
|
|
|
|
//启动任务调度服务
|
|
Start();
|
|
Console.WriteLine("已启动");
|
|
QMFrameWork.Log.LogManager.LogHelper.Info(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已启动" });
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动服务", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// TopShelf's method delegated to <see cref="Start()"/>.
|
|
/// </summary>
|
|
public bool Start(HostControl hostControl)
|
|
{
|
|
try
|
|
{
|
|
//启动远程服务
|
|
if (PublishHost.State != CommunicationState.Opening)
|
|
PublishHost.Open();
|
|
|
|
//启动任务调度服务
|
|
Start();
|
|
Console.WriteLine("已启动");
|
|
QMFrameWork.Log.LogManager.LogHelper.Info(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已启动" });
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动服务", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
public bool StopService()
|
|
{
|
|
try
|
|
{
|
|
//停止远程服务
|
|
if (PublishHost.State != CommunicationState.Opening)
|
|
PublishHost.Close();
|
|
|
|
//停止任务调度服务
|
|
Stop();
|
|
Console.WriteLine("已停止");
|
|
QMFrameWork.Log.LogManager.LogHelper.Info(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已停止" });
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止服务", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// TopShelf's method delegated to <see cref="Stop()"/>.
|
|
/// </summary>
|
|
public bool Stop(HostControl hostControl)
|
|
{
|
|
try
|
|
{
|
|
//停止远程服务
|
|
if (PublishHost.State != CommunicationState.Opening)
|
|
PublishHost.Close();
|
|
|
|
//停止任务调度服务
|
|
Stop();
|
|
Console.WriteLine("已停止");
|
|
QMFrameWork.Log.LogManager.LogHelper.Info(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "服务已停止" });
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止服务", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Pauses all activity in scheduler.
|
|
/// </summary>
|
|
public virtual void Pause()
|
|
{
|
|
//scheduler.PauseAll();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resumes all activity in server.
|
|
/// </summary>
|
|
public void Resume()
|
|
{
|
|
//scheduler.ResumeAll();
|
|
}
|
|
|
|
/// <summary>
|
|
/// TopShelf's method delegated to <see cref="Pause()"/>.
|
|
/// </summary>
|
|
public bool Pause(HostControl hostControl)
|
|
{
|
|
Pause();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// TopShelf's method delegated to <see cref="Resume()"/>.
|
|
/// </summary>
|
|
public bool Continue(HostControl hostControl)
|
|
{
|
|
Resume();
|
|
return true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
|
/// </summary>
|
|
public virtual void Dispose()
|
|
{
|
|
// no-op for now
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 启动
|
|
|
|
public void Start()
|
|
{
|
|
_sched = _sfactory.GetScheduler();
|
|
|
|
//添加监听
|
|
JobListener listener = new JobListener();
|
|
listener.MyTaskServer = this;
|
|
listener.Name = "listener1";
|
|
_sched.ListenerManager.AddJobListener(listener);
|
|
|
|
//加载任务
|
|
this.LoadTasks();
|
|
//加载计划
|
|
this.LoadPlans();
|
|
|
|
//启动
|
|
_sched.Start();
|
|
Running = true;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 停止
|
|
|
|
public void Stop()
|
|
{
|
|
_sched.Shutdown(false);
|
|
Running = false;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 加载任务
|
|
|
|
public void LoadTasks()
|
|
{
|
|
_tasks = this.GetTaskList();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 获取任务列表
|
|
|
|
public List<TaskInfo> GetTaskList()
|
|
{
|
|
List<TaskInfo> tasks = null;
|
|
XmlHelper xml = new XmlHelper(Configuration.TaskConfigPath());
|
|
tasks = xml.GetData<TaskInfo>("Task/TaskDetail");
|
|
return tasks;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 计划管理
|
|
|
|
/// <summary>
|
|
/// 载入计划
|
|
/// </summary>
|
|
public void LoadPlans()
|
|
{
|
|
_plans = new Dictionary<JobKey, PlanInfo>();
|
|
|
|
//获取计划信息
|
|
List<PlanInfo> plans = new PlanInfoManage().GetPlanList();
|
|
|
|
//初始化监控信息
|
|
MonitorInfos = new Dictionary<JobKey, MonitorInfo>();
|
|
|
|
//循环添加计划
|
|
foreach (PlanInfo plan in plans)
|
|
{
|
|
if (plan.IsUse == "false")
|
|
continue;
|
|
|
|
IJobDetail job = null;
|
|
ICronTrigger trigger=null;
|
|
TaskInfo task = null;
|
|
|
|
this.GetJobAndTrigger(plan, out job, out trigger, out task);
|
|
|
|
if (task == null)
|
|
continue;
|
|
|
|
_plans.Add(job.Key, plan);
|
|
|
|
//添加监控信息
|
|
MonitorInfo monitor = new MonitorInfo();
|
|
monitor.PlanID = plan.PlanID;
|
|
monitor.PlanName = plan.PlanName;
|
|
monitor.TaskID = task.TaskID;
|
|
monitor.TaskName = task.TaskName;
|
|
monitor.IsUse = bool.Parse(plan.IsUse);
|
|
monitor.IsNormal = true;
|
|
MonitorInfos.Add(job.Key,monitor);
|
|
|
|
//添加触发器
|
|
_sched.ScheduleJob(job, trigger);
|
|
monitor.Running = true;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
//获取作业与触发器
|
|
private void GetJobAndTrigger(PlanInfo plan, out IJobDetail job, out ICronTrigger trigger, out TaskInfo task)
|
|
{
|
|
//创建触发器表达式
|
|
CronExpression ce = new CronExpression();
|
|
ce.Build(plan);
|
|
|
|
//查找对应任务
|
|
task = _tasks.Find(p => p.TaskID == plan.TaskID);
|
|
if (task == null)
|
|
{
|
|
job = null;
|
|
trigger = null;
|
|
return;
|
|
}
|
|
|
|
//创建计划
|
|
string rootPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
|
|
Assembly Asse = Assembly.LoadFile(rootPath + @"\" + task.AssemblyFile);
|
|
Type taskType = Asse.GetType(task.TaskType);
|
|
job = JobBuilder.Create(taskType).WithIdentity(plan.PlanID, "group1").Build();
|
|
|
|
//创建触发器
|
|
TriggerBuilder tb = TriggerBuilder.Create()
|
|
.WithIdentity("tr" + plan.PlanID, "group1")
|
|
.WithCronSchedule(ce.ToString());
|
|
|
|
//设置计划开始日期
|
|
if (plan.PlanStartDate != new DateTime())
|
|
{
|
|
tb = tb.StartAt(DateTimeOffset.Parse(plan.PlanStartDate.ToString("yyyy-MM-dd")));
|
|
}
|
|
//设置计划结束日期
|
|
if (plan.PlanEndDate != new DateTime())
|
|
{
|
|
tb = tb.EndAt(DateTimeOffset.Parse(plan.PlanEndDate.ToString("yyyy-MM-dd")));
|
|
}
|
|
|
|
trigger = (ICronTrigger)tb.Build();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加计划
|
|
/// </summary>
|
|
/// <param name="plan"></param>
|
|
/// <returns></returns>
|
|
public bool AddPlan(PlanInfo plan)
|
|
{
|
|
try
|
|
{
|
|
if (Running == false)
|
|
return true;
|
|
|
|
IJobDetail job = null;
|
|
ICronTrigger trigger = null;
|
|
TaskInfo task = null;
|
|
|
|
if (plan.IsUse == "false")
|
|
return true;
|
|
|
|
this.GetJobAndTrigger(plan, out job, out trigger, out task);
|
|
|
|
if (task == null)
|
|
return true;
|
|
|
|
_plans.Add(job.Key, plan);
|
|
|
|
//添加监控信息
|
|
MonitorInfo monitor = new MonitorInfo();
|
|
monitor.PlanID = plan.PlanID;
|
|
monitor.PlanName = plan.PlanName;
|
|
monitor.TaskID = task.TaskID;
|
|
monitor.TaskName = task.TaskName;
|
|
MonitorInfos.Add(job.Key, monitor);
|
|
|
|
//添加触发器
|
|
_sched.ScheduleJob(job, trigger);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "添加计划", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
//更新计划
|
|
public bool UpdatePlan(PlanInfo plan)
|
|
{
|
|
bool r;
|
|
r=this.DeletePlan(plan);
|
|
|
|
if (r == false)
|
|
{
|
|
return r;
|
|
}
|
|
|
|
r=this.AddPlan(plan);
|
|
|
|
return r;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除计划
|
|
/// </summary>
|
|
/// <param name="plan"></param>
|
|
/// <returns></returns>
|
|
public bool DeletePlan(PlanInfo plan)
|
|
{
|
|
try
|
|
{
|
|
if (Running == false)
|
|
return false;
|
|
|
|
JobKey key = null;
|
|
PlanInfo updatePlan = null;
|
|
|
|
updatePlan = this.GetPlanInfo(plan.PlanID, out key);
|
|
|
|
if (key == null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
MonitorInfo monitor = this.GetMonitorInfo(key);
|
|
|
|
if (monitor.Running == false)
|
|
{
|
|
_sched.ResumeJob(key);
|
|
_sched.DeleteJob(key);
|
|
|
|
_plans.Remove(key);
|
|
MonitorInfos.Remove(key);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "删除计划", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 启动计划
|
|
/// </summary>
|
|
/// <param name="plan"></param>
|
|
/// <returns></returns>
|
|
public bool StartPlan(PlanInfo plan)
|
|
{
|
|
try
|
|
{
|
|
if (Running == false)
|
|
return false;
|
|
|
|
IJobDetail job = null;
|
|
ICronTrigger trigger = null;
|
|
TaskInfo task = null;
|
|
JobKey key = null;
|
|
|
|
PlanInfo startPlan = null;
|
|
|
|
startPlan = this.GetPlanInfo(plan.PlanID, out key);
|
|
if (startPlan != null)
|
|
return true;
|
|
|
|
this.GetJobAndTrigger(plan, out job, out trigger, out task);
|
|
|
|
if (task == null)
|
|
return true;
|
|
|
|
_plans.Add(job.Key, plan);
|
|
|
|
//添加监控信息
|
|
MonitorInfo monitor = new MonitorInfo();
|
|
monitor.PlanID = plan.PlanID;
|
|
monitor.PlanName = plan.PlanName;
|
|
monitor.TaskID = task.TaskID;
|
|
monitor.TaskName = task.TaskName;
|
|
MonitorInfos.Add(job.Key, monitor);
|
|
|
|
//添加触发器
|
|
_sched.ScheduleJob(job, trigger);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "启动计划", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 停止计划
|
|
/// </summary>
|
|
/// <param name="plan"></param>
|
|
/// <returns></returns>
|
|
public bool StopPlan(PlanInfo plan)
|
|
{
|
|
try
|
|
{
|
|
if (Running == false)
|
|
return false;
|
|
|
|
JobKey key = null;
|
|
PlanInfo stopPlan = null;
|
|
|
|
stopPlan = this.GetPlanInfo(plan.PlanID, out key);
|
|
|
|
if (stopPlan == null)
|
|
return true;
|
|
|
|
stopPlan.IsUse = "false";
|
|
|
|
MonitorInfo monitor = this.GetMonitorInfo(key);
|
|
if (monitor.Running == false)
|
|
{
|
|
_sched.ResumeJob(key);
|
|
_sched.DeleteJob(key);
|
|
|
|
_plans.Remove(key);
|
|
MonitorInfos.Remove(key);
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "停止计划", ErrorInfo = ex });
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private PlanInfo GetPlanInfo(string planID,out JobKey key)
|
|
{
|
|
PlanInfo plan = null;
|
|
key = null;
|
|
foreach (JobKey jobkey in _plans.Keys)
|
|
{
|
|
if (_plans[jobkey].PlanID == planID)
|
|
{
|
|
plan = _plans[jobkey];
|
|
key = jobkey;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return plan;
|
|
}
|
|
|
|
private MonitorInfo GetMonitorInfo(JobKey key)
|
|
{
|
|
if (MonitorInfos.ContainsKey(key) == true)
|
|
{
|
|
return MonitorInfos[key];
|
|
}
|
|
else
|
|
{
|
|
return null;
|
|
}
|
|
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 状态监控
|
|
|
|
/// <summary>
|
|
/// 获取监控信息
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
public List<MonitorInfo> GetPlanMonitorInfos()
|
|
{
|
|
try
|
|
{
|
|
List<MonitorInfo> returnMonitors = new List<MonitorInfo>();
|
|
|
|
//获取监控信息
|
|
List<MonitorInfo> monitors = MonitorInfos.Values.ToList();
|
|
|
|
//获取计划信息
|
|
List<PlanInfo> plans = new PlanInfoManage().GetPlanList();
|
|
|
|
//关联
|
|
foreach (PlanInfo plan in plans)
|
|
{
|
|
MonitorInfo monitor = null;
|
|
|
|
TaskInfo task = _tasks.Find(p => p.TaskID == plan.TaskID);
|
|
|
|
monitor = monitors.Find(p => p.PlanID == plan.PlanID);
|
|
if (monitor == null)
|
|
{
|
|
monitor = new MonitorInfo();
|
|
monitor.Running = false;
|
|
monitor.IsUse = false;
|
|
}
|
|
monitor.PlanID = plan.PlanID;
|
|
monitor.PlanName = plan.PlanName;
|
|
monitor.TaskID = plan.TaskID;
|
|
monitor.TaskName = task.TaskName;
|
|
|
|
string intervalType = "";
|
|
string periodType = "";
|
|
switch (plan.IntervalType)
|
|
{
|
|
case "s":
|
|
intervalType = "秒";
|
|
break;
|
|
case "m":
|
|
intervalType = "分";
|
|
break;
|
|
case "h":
|
|
intervalType = "小时";
|
|
break;
|
|
}
|
|
|
|
switch (plan.PeriodType)
|
|
{
|
|
case "d":
|
|
if (string.IsNullOrEmpty(plan.OnceTime) == false)
|
|
{
|
|
periodType = "每天";
|
|
}
|
|
else
|
|
{
|
|
periodType = "每" + plan.Interval + intervalType;
|
|
}
|
|
break;
|
|
case "w":
|
|
periodType = "每周";
|
|
break;
|
|
case "m":
|
|
if (plan.Period == 1)
|
|
{
|
|
periodType = "每月";
|
|
}
|
|
else
|
|
{
|
|
periodType = "每" + plan.Period.ToString() + "月";
|
|
}
|
|
break;
|
|
}
|
|
|
|
monitor.ExecuteInterval = periodType;
|
|
monitor.Remark = plan.Remark;
|
|
|
|
returnMonitors.Add(monitor);
|
|
|
|
}
|
|
|
|
return returnMonitors;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
QMFrameWork.Log.LogManager.LogHelper.Error(
|
|
new QMFrameWork.Log.LogInfo { ClientIP = "localhost", UserName = "admin", Info = "获取监控信息", ErrorInfo = ex });
|
|
throw ex;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 输出监控信息
|
|
/// </summary>
|
|
/// <param name="monitor"></param>
|
|
public void OutputMonitor(MonitorInfo monitor)
|
|
{
|
|
if (this.ExportMonitorEvent != null)
|
|
{
|
|
this.ExportMonitorEvent(this, monitor);
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|