添加项目文件。

This commit is contained in:
dell
2023-03-03 16:07:50 +08:00
parent 2c462551b6
commit 011039960e
585 changed files with 362460 additions and 0 deletions

View File

@ -0,0 +1,11 @@
using System.Threading.Tasks;
using HT.Cloud.Code;
namespace HT.Cloud.Service.AutoJob
{
public interface IJobTask
{
//执行方法
Task<AlwaysResult> Start();
}
}

View File

@ -0,0 +1,32 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Spi;
using System;
namespace HT.Cloud.Service.AutoJob
{
/// <summary>
/// 依赖注入必须代替原本的SimpleJobFactory
/// </summary>
public class IOCJobFactory : IJobFactory
{
private readonly IServiceProvider _serviceProvider;
public IOCJobFactory(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
public IJob NewJob(TriggerFiredBundle bundle, IScheduler scheduler)
{
var serviceScope = _serviceProvider.CreateScope(); // 获得一个ioc对象指定创建scope级别的实例在job里面需要依赖注入ef但是startup里面配置的ef是scope级别的必须指定为scope不然报错。不写的话默认是单例。
return serviceScope.ServiceProvider.GetService(bundle.JobDetail.JobType) as IJob; // 依赖注入一个 job 然后返回
}
public void ReturnJob(IJob job)
{
var disposable = job as IDisposable;
disposable?.Dispose();
}
}
}

View File

@ -0,0 +1,46 @@
using Microsoft.AspNetCore.Hosting;
using SqlSugar;
using System;
using System.Threading.Tasks;
using HT.Cloud.Code;
using HT.Cloud.Domain.SystemSecurity;
using HT.Cloud.Service.SystemSecurity;
namespace HT.Cloud.Service.AutoJob
{
[ServiceDescription("服务器监控")]
public class SaveServerStateJob : IJobTask
{
private IWebHostEnvironment _hostingEnvironment;
private ServerStateService _server;
public SaveServerStateJob(ISqlSugarClient context)
{
_hostingEnvironment = GlobalContext.HostingEnvironment;
_server = new ServerStateService(context);
}
public async Task<AlwaysResult> Start()
{
AlwaysResult obj = new AlwaysResult();
try
{
ServerStateEntity entity = new ServerStateEntity();
var computer = ComputerHelper.GetComputerInfo();
entity.F_ARM = computer.RAMRate;
entity.F_CPU = computer.CPURate;
entity.F_IIS = "0";
entity.F_WebSite = _hostingEnvironment.ContentRootPath;
await _server.SubmitForm(entity);
obj.state = ResultType.success.ToString();
obj.message = "服务器状态更新成功!";
}
catch (Exception ex)
{
obj.state = ResultType.error.ToString();
obj.message = "服务器状态更新失败!" + ex.Message;
}
return obj;
}
}
}

View File

@ -0,0 +1,146 @@
using Microsoft.Extensions.Hosting;
using Quartz;
using Quartz.Impl.Triggers;
using Quartz.Spi;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using HT.Cloud.Code;
using HT.Cloud.Domain.SystemSecurity;
using HT.Cloud.Service.SystemSecurity;
namespace HT.Cloud.Service.AutoJob
{
/// <summary>
/// quartz 主机服务
/// </summary>
[DisallowConcurrentExecution]
public class JobCenter : IHostedService
{
/// <summary>
/// 定时作业计划生成工厂这一项在startup有配置集群模式
/// </summary>
private readonly ISchedulerFactory _schedulerFactory;
/// <summary>
/// 定时作业工厂
/// </summary>
private readonly IJobFactory _jobFactory;
private OpenJobsService _service;
private IScheduler _scheduler;
/// <summary>
/// 构造注入
/// </summary>
public JobCenter(OpenJobsService service, ISchedulerFactory schedulerFactory, IJobFactory jobFactory)
{
_service = service;
_jobFactory = jobFactory;
_schedulerFactory = schedulerFactory;
}
/// <summary>
/// 批量启动定时任务
/// </summary>
/// <param name="cancellationToken"></param>
/// <returns></returns>
public async Task StartAsync(CancellationToken cancellationToken)
{
_scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
_scheduler.JobFactory = _jobFactory;
if (GlobalContext.SystemConfig.IsCluster == false || GlobalContext.SystemConfig.NeedClear == true)
{
await _scheduler.Clear();
}
List<OpenJobEntity> obj = await _service.GetAllList(null);
obj = obj.Where(a => a.F_EnabledMark == true).ToList();
if (obj.Count > 0)
{
await AddScheduleJob(obj, cancellationToken);
}
await _scheduler.Start();
//if (!GlobalContext.SystemConfig.Debug)
//{
// List<OpenJobEntity> obj = await new OpenJobService().GetList(null);
// if (obj.Count>0)
// {
// AddScheduleJob(obj);
// }
//}
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await ClearScheduleJob();
}
#region
/// <summary>
/// 添加任务计划
/// </summary>
/// <returns></returns>
private async Task AddScheduleJob(List<OpenJobEntity> entityList, CancellationToken cancellationToken)
{
try
{
foreach (OpenJobEntity entity in entityList)
{
entity.F_StarRunTime = DateTime.Now;
entity.F_EndRunTime = DateTime.Now.AddSeconds(-1);
DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(entity.F_StarRunTime, 1);
DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(DateTime.MaxValue.AddDays(-1), 1);
await _service.SubmitForm(entity, entity.F_Id);
ICronTrigger trigger = (ICronTrigger)TriggerBuilder.Create()
.StartAt(starRunTime)
.EndAt(endRunTime)
.WithIdentity(entity.F_JobName, entity.F_JobGroup)
.WithCronSchedule(entity.F_CronExpress)
.Build();
((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
// 判断数据库中有没有记录过有的话quartz会自动从数据库中提取信息创建 schedule
if (!await _scheduler.CheckExists(new JobKey(entity.F_JobName, entity.F_JobGroup)))
{
IJobDetail job = JobBuilder.Create<JobExecute>().WithIdentity(entity.F_JobName, entity.F_JobGroup).Build();
job.JobDataMap.Add("F_Id", entity.F_Id);
await _scheduler.ScheduleJob(job, trigger, cancellationToken);
//存在相同名字的Job或Trigger,更新调度任务
//IList<ICronTrigger> triggers = new List<ICronTrigger> { trigger };
//await _scheduler.ScheduleJob(job, new ReadOnlyCollection<ICronTrigger>(triggers), true);
}
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#endregion
#region
/// <summary>
/// 清除任务计划
/// </summary>
/// <returns></returns>
public async Task ClearScheduleJob()
{
try
{
await _scheduler.Clear();
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#endregion
}
}

View File

@ -0,0 +1,211 @@
using Microsoft.Extensions.DependencyInjection;
using Quartz;
using Quartz.Impl.Triggers;
using Quartz.Spi;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Threading.Tasks;
using HT.Cloud.Code;
using HT.Cloud.DataBase;
using HT.Cloud.Domain.SystemSecurity;
using HT.Cloud.Service.SystemSecurity;
namespace HT.Cloud.Service.AutoJob
{
public class JobExecute : IJob
{
private IScheduler _scheduler;
private ISchedulerFactory _schedulerFactory;
private IJobFactory _iocJobfactory;
private readonly IHttpClientFactory _httpClient;
public JobExecute(ISchedulerFactory schedulerFactory, IJobFactory iocJobfactory, IHttpClientFactory httpClient)
{
_scheduler = schedulerFactory.GetScheduler().GetAwaiter().GetResult();
_scheduler.JobFactory = iocJobfactory;
_schedulerFactory = schedulerFactory;
_iocJobfactory = iocJobfactory;
_httpClient = httpClient;
}
public Task Execute(IJobExecutionContext context)
{
return Task.Run(async () =>
{
string jobId = "";
JobDataMap jobData = null;
OpenJobEntity dbJobEntity = null;
DateTime now = DateTime.Now;
var dbContext = GlobalContext.RootServices.GetRequiredService<ISqlSugarClient>();
try
{
jobData = context.JobDetail.JobDataMap;
jobId = jobData.GetString("F_Id");
// 获取数据库中的任务
dbJobEntity = await dbContext.Queryable<OpenJobEntity>().Where(a=>a.F_Id== jobId).FirstAsync();
if (dbJobEntity != null)
{
if (dbJobEntity.F_EnabledMark == true)
{
CronTriggerImpl trigger = context.Trigger as CronTriggerImpl;
if (trigger != null)
{
if (trigger.CronExpressionString != dbJobEntity.F_CronExpress)
{
// 更新任务周期
trigger.CronExpressionString = dbJobEntity.F_CronExpress;
await _scheduler.RescheduleJob(trigger.Key, trigger);
return;
}
#region
OpenJobLogEntity log = new OpenJobLogEntity();
log.F_Id = Utils.GuId();
log.F_JobId = jobId;
log.F_JobName = dbJobEntity.F_JobName;
log.F_CreatorTime = now;
AlwaysResult result = new AlwaysResult();
if (dbJobEntity.F_JobType == 0)
{
//反射执行就行
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
//反射取指定前后缀的dll
var referencedAssemblies = Directory.GetFiles(path, "HT.Cloud.*.dll").Select(Assembly.LoadFrom).ToArray();
var types = referencedAssemblies
.SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces()
.Contains(typeof(IJobTask)))).ToArray();
string filename = dbJobEntity.F_FileName;
var implementType = types.Where(x => x.IsClass && x.FullName == filename).FirstOrDefault();
var obj = System.Activator.CreateInstance(implementType, dbContext); // 创建实例(带参数)
MethodInfo method = implementType.GetMethod("Start", new Type[] { }); // 获取方法信息
object[] parameters = null;
result = ((Task<AlwaysResult>)method.Invoke(obj, parameters)).GetAwaiter().GetResult(); // 调用方法,参数为空
if (result.state.ToString() == ResultType.success.ToString())
{
log.F_EnabledMark = true;
log.F_Description = "执行成功," + result.message.ToString();
}
else
{
log.F_EnabledMark = false;
log.F_Description = "执行失败," + result.message.ToString();
}
}
else if (dbJobEntity.F_JobType == 5)
{
var dbContextTemp = dbContext.AsTenant().GetConnectionScope(dbJobEntity.F_JobDBProvider);
try
{
dbContextTemp.Ado.BeginTran();
if (!string.IsNullOrEmpty(dbJobEntity.F_JobSqlParm))
{
var dic = dbJobEntity.F_JobSqlParm.ToObject<Dictionary<string, object>>();
List<SugarParameter> list = new List<SugarParameter>();
foreach (var item in dic)
{
list.Add(new SugarParameter(item.Key, item.Value));
}
var dbResult = await dbContextTemp.Ado.SqlQueryAsync<dynamic>(dbJobEntity.F_JobSql, list);
log.F_EnabledMark = true;
log.F_Description = "执行成功," + dbResult.ToJson();
}
else
{
var dbResult = await dbContextTemp.Ado.SqlQueryAsync<dynamic>(dbJobEntity.F_JobSql);
log.F_EnabledMark = true;
log.F_Description = "执行成功," + dbResult.ToJson();
}
dbContextTemp.Ado.CommitTran();
}
catch (Exception ex)
{
log.F_EnabledMark = false;
log.F_Description = "执行失败," + ex.Message;
dbContextTemp.Ado.RollbackTran();
}
}
else
{
HttpMethod method = HttpMethod.Get;
switch (dbJobEntity.F_JobType)
{
case 1:
method = HttpMethod.Get;
break;
case 2:
method = HttpMethod.Post;
break;
case 3:
method = HttpMethod.Put;
break;
case 4:
method = HttpMethod.Delete;
break;
}
var dic = dbJobEntity.F_RequestHeaders.ToObject<Dictionary<string, string>>();
if (dic == null)
{
dic = new Dictionary<string, string>();
}
//请求头添加租户号
dic.Add("dbNumber", dbJobEntity.F_DbNumber);
try
{
var temp = await new HttpWebClient(_httpClient).ExecuteAsync(dbJobEntity.F_RequestUrl, method, dbJobEntity.F_RequestString, dic);
log.F_EnabledMark = true;
log.F_Description = $"执行成功。{temp}";
}
catch (Exception ex)
{
log.F_EnabledMark = false;
log.F_Description = "执行失败," + ex.Message.ToString();
}
}
#endregion
dbContext.Ado.BeginTran();
if (log.F_EnabledMark == true)
{
await dbContext.Updateable<OpenJobEntity>(a => new OpenJobEntity
{
F_LastRunMark = true,
F_LastRunTime = now,
}).Where(a => a.F_Id == jobId).ExecuteCommandAsync();
}
else
{
await dbContext.Updateable<OpenJobEntity>(a => new OpenJobEntity
{
F_LastRunMark = false,
F_LastRunTime = now,
F_LastRunErrTime = now,
F_LastRunErrMsg = log.F_Description
}).Where(a => a.F_Id == jobId).ExecuteCommandAsync();
}
if (dbJobEntity.F_IsLog == "是")
{
dbContext.Insertable(log).ExecuteCommand();
}
dbContext.Ado.CommitTran();
}
}
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
});
}
}
}