public Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken cancellationToken = default(CancellationToken)) { try { QuartzDbContext db = Program.Host.Services.GetService <QuartzDbContext>(); var logFaoctory = Program.Host.Services.GetService <ILoggerFactory>(); var log = logFaoctory.CreateLogger <JobUpdateListens>(); string machine = Environment.MachineName; var item = db.QuartzTask.FirstOrDefault(w => w.IsDelete == 0 && w.TaskName == context.JobDetail.Key.Name && w.GroupName == context.JobDetail.Key.Group && w.MachineName == machine && w.InstanceId == context.Scheduler.SchedulerInstanceId); if (jobException != null) { item.Status = (int)TaskStatus.Faulted; item.Remark = Newtonsoft.Json.JsonConvert.SerializeObject(jobException); log.LogError("Job执行错误,name:{0},Group:{1}", context.JobDetail.Key.Name, context.JobDetail.Key.Group); } else { item.Status = (int)TaskStatus.RanToCompletion; item.RecentRunTime = context.FireTimeUtc.DateTime; if (context.NextFireTimeUtc.HasValue) { item.NextFireTime = context.NextFireTimeUtc.Value.DateTime; } } db.Update <QuartzTask>(item); db.SaveChanges(); } catch (Exception ep) { //context.Scheduler.Interrupt(context.JobDetail.Key); var logFaoctory = Program.Host.Services.GetService <ILoggerFactory>(); var log = logFaoctory.CreateLogger <JobUpdateListens>(); log.LogError(0, ep, "JobWasExecuted:Job执行错误,name:{0},Group:{1}", context.JobDetail.Key.Name, context.JobDetail.Key.Group); } return(Task.FromResult(true)); }
public Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken)) { try { string machine = Environment.MachineName; QuartzDbContext db = Program.Host.Services.GetService <QuartzDbContext>(); var item = db.QuartzTask.FirstOrDefault(w => w.IsDelete == 0 && w.TaskName == context.JobDetail.Key.Name && w.GroupName == context.JobDetail.Key.Group && w.MachineName == machine && w.InstanceId == context.Scheduler.SchedulerInstanceId); item.Status = (int)TaskStatus.WaitingToRun; db.Update <QuartzTask>(item); db.SaveChanges(); } catch (Exception ep) { //context.Scheduler.Interrupt(context.JobDetail.Key); var logFaoctory = Program.Host.Services.GetService <ILoggerFactory>(); var log = logFaoctory.CreateLogger <JobUpdateListens>(); log.LogError(0, ep, "JobToBeExecuted:Job执行错误,name:{0},Group:{1}", context.JobDetail.Key.Name, context.JobDetail.Key.Group); } return(Task.FromResult(true)); }
private static IScheduler RunProgramRunExample(ILoggerFactory loggerFact) { var log = loggerFact.CreateLogger <Program>(); try { var config = Host.Services.GetService <IConfiguration>(); // Grab the Scheduler instance from the Factory NameValueCollection properties = new NameValueCollection { ["quartz.scheduler.instanceName"] = QuartzOpt.InstanceName, ["quartz.scheduler.instanceId"] = QuartzOpt.InsatanceId, ["quartz.threadPool.type"] = "Quartz.Simpl.SimpleThreadPool, Quartz", ["quartz.threadPool.threadCount"] = "5", ["quartz.jobStore.misfireThreshold"] = "60000", ["quartz.jobStore.type"] = "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz", ["quartz.jobStore.useProperties"] = "false", ["quartz.jobStore.dataSource"] = "default", ["quartz.jobStore.tablePrefix"] = "QRTZ_", ["quartz.jobStore.clustered"] = "true", ["quartz.jobStore.driverDelegateType"] = "Quartz.Impl.AdoJobStore.MySQLDelegate, Quartz", ["quartz.dataSource.default.connectionString"] = config.GetConnectionString("QuatrzClustDatabase"), ["quartz.dataSource.default.provider"] = "MySql", ["quartz.serializer.type"] = "json", ["quartz.scheduler.exporter.type"] = "Quartz.Simpl.RemotingSchedulerExporter, Quartz", ["quartz.scheduler.exporter.port"] = "555", ["quartz.scheduler.exporter.bindName"] = "QuartzScheduler", ["quartz.scheduler.exporter.channelType"] = "tcp", ["quartz.scheduler.exporter.channelName"] = "httpQuartz", ["quartz.scheduler.exporter.rejectRemoteRequests"] = "true" }; StdSchedulerFactory factory = new StdSchedulerFactory(properties); IScheduler scheduler = factory.GetScheduler().GetAwaiter().GetResult(); string machine = Environment.MachineName; QuartzDbContext db = Host.Services.GetService <QuartzDbContext>(); var listQuartzTask = db.QuartzTask.Where(w => w.IsDelete == 0 && w.MachineName == machine && w.InstanceId == QuartzOpt.InsatanceId) .ToListAsync().GetAwaiter().GetResult(); log.LogDebug("从数据库获取task记录,详细信息:{0}", Newtonsoft.Json.JsonConvert.SerializeObject(listQuartzTask)); Dictionary <string, Assembly> collAssembly = new Dictionary <string, Assembly>(); foreach (var item in listQuartzTask) { //加载程序集 if (!string.IsNullOrEmpty(item.AssemblyName) && !collAssembly.ContainsKey(item.AssemblyName)) { try { collAssembly[item.AssemblyName] = AssemblyHelp.GetAssemblyByteByAssemblyName( Path.Combine(Directory.GetCurrentDirectory(), "AssemblyColl"), item.AssemblyName); } catch (Exception ep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, ep, "没有找到程序集."); Task.Delay(10000); continue; } } } // and start it off scheduler.Start(); // if (!QuartzOpt.IsSlave) // { var task = Task.Run(() => { bool isClear = QuartzOpt.IsClear; log.LogInformation("job监控程序开始循环,间隔为15秒"); while (true) { try { if (scheduler != null) { log.LogDebug("检查scheduler是否开始"); if (scheduler.IsStarted) { if (isClear) { scheduler.Clear().GetAwaiter().GetResult(); isClear = false; } log.LogDebug("scheduler已经开始"); db = Host.Services.GetService <QuartzDbContext>(); listQuartzTask = db.QuartzTask.Where(w => w.IsDelete == 0 && w.MachineName == machine && w.InstanceId == QuartzOpt.InsatanceId) .ToListAsync().GetAwaiter().GetResult(); log.LogDebug("从数据库获取task记录,详细信息:{0}", Newtonsoft.Json.JsonConvert.SerializeObject(listQuartzTask)); foreach (var item in listQuartzTask) { //加载程序集 if (!string.IsNullOrEmpty(item.AssemblyName) && !collAssembly.ContainsKey(item.AssemblyName)) { try { collAssembly[item.AssemblyName] = AssemblyHelp.GetAssemblyByteByAssemblyName( Path.Combine(Directory.GetCurrentDirectory(), "AssemblyColl"), item.AssemblyName); } catch (Exception ep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, ep, "没有找到程序集."); Task.Delay(10000); continue; } } log.LogDebug("开始检查task:{0}", Newtonsoft.Json.JsonConvert.SerializeObject(item)); var jobKey = new JobKey(item.TaskName, item.GroupName); var triggerKey = new TriggerKey(item.TaskName, item.GroupName); if (scheduler.CheckExists(jobKey).Result) { var jobDetai = scheduler.GetJobDetail(jobKey); var trigger = scheduler.GetTrigger(triggerKey); log.LogDebug("此task已经存在scheduler中,数据库状态:{0},scheduer中的状态:{1}.trigger状态:{2}" , ((OperateStatus)item.OperateStatus).ToString(), jobDetai.Status.ToString(), trigger.Status.ToString()); if ((OperateStatus)item.OperateStatus == OperateStatus.Stop) { log.LogInformation("删除schduler中的job:{0}", jobKey.ToString()); if (!scheduler.DeleteJob(jobKey).GetAwaiter().GetResult()) { log.LogError("删除job失败。name:{0},group:{1}", jobKey.Name, jobKey.Group); } } else { if (jobDetai.IsFaulted) { if (jobDetai.Exception != null) { log.LogError(10005, jobDetai.Exception, "job faulted"); } var jobItem = db.QuartzTask.FirstOrDefault(w => w.IsDelete == 0 && w.TaskName == jobKey.Name && w.GroupName == jobKey.Group && w.MachineName == machine && w.InstanceId == scheduler.SchedulerInstanceId); item.Status = (int)TaskStatus.Faulted; item.OperateStatus = (int)OperateStatus.Stop; db.Update <QuartzTask>(jobItem); db.SaveChanges(); } else { if (jobDetai.Status != TaskStatus.Running && jobDetai.Status != TaskStatus.RanToCompletion && jobDetai.Status != TaskStatus.WaitingForActivation && jobDetai.Status != TaskStatus.WaitingForChildrenToComplete && jobDetai.Status != TaskStatus.WaitingToRun) { var interTask = scheduler.Interrupt(jobKey, new CancellationToken(true)) .GetAwaiter().GetResult(); jobDetai.Start(); } } } var triggerListener = scheduler.ListenerManager.GetTriggerListener("triggerUpdate"); if (triggerListener == null) { triggerListener = new TriggerUpdateListens("trigger" + item.TaskName); IMatcher <TriggerKey> triggermatcher = KeyMatcher <TriggerKey> .KeyEquals(triggerKey); scheduler.ListenerManager.AddTriggerListener(triggerListener, triggermatcher); } var jobListener = scheduler.ListenerManager.GetJobListener("jobupdateListens"); if (jobListener == null) { IJobListener jobUpdateListener = new JobUpdateListens("job" + item.TaskName); IMatcher <JobKey> jobmatcher = KeyMatcher <JobKey> .KeyEquals(jobKey); scheduler.ListenerManager.AddJobListener(jobUpdateListener, jobmatcher); } } else { log.LogInformation("添加新的job,判断是否状态为停止。"); if ((OperateStatus)item.OperateStatus != OperateStatus.Stop) { log.LogInformation("添加新的job"); var assemblyName = item.AssemblyName; var className = item.ClassName; Type jobTaskType = null; try { jobTaskType = AssemblyHelp.GetTypeByAssemblyNameAndClassName(collAssembly[item.AssemblyName], className); log.LogInformation("找到类型,type:{0}", className); } catch (Exception ep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, ep, "没有找到type."); } if (jobTaskType == null) { try { jobTaskType = AssemblyHelp .GetTypeByCurrentAssemblyNameAndClassName(className, Assembly.GetExecutingAssembly()); if (jobTaskType == null) { log.LogInformation("没有找到类型"); continue; } log.LogInformation("找到类型,type:{0}", className); } catch (Exception ep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, ep, "没有找到类型."); continue; } } IJobDetail job = JobBuilder.Create(jobTaskType) .WithIdentity(item.TaskName, item.GroupName) .Build(); ITrigger trigger = TriggerBuilder.Create() .WithIdentity(item.TaskName, item.GroupName) .StartNow() .WithCronSchedule(item.CronExpressionString) .Build(); scheduler.ScheduleJob(job, trigger).GetAwaiter().GetResult(); log.LogInformation("添加成功,type:{0}", className); ITriggerListener triggerListener = new TriggerUpdateListens("trigger" + item.TaskName); IMatcher <TriggerKey> triggermatcher = KeyMatcher <TriggerKey> .KeyEquals(trigger.Key); scheduler.ListenerManager.AddTriggerListener(triggerListener, triggermatcher); IJobListener jobUpdateListener = new JobUpdateListens("job" + item.TaskName); IMatcher <JobKey> jobmatcher = KeyMatcher <JobKey> .KeyEquals(job.Key); scheduler.ListenerManager.AddJobListener(jobUpdateListener, jobmatcher); } } } } else { log.LogInformation("scheduler is not IsStarted"); } } else { log.LogInformation("scheduler is null"); } } catch (Exception ep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, ep, "task监控程序执行错误."); } Thread.Sleep(15000); } }); // } // else // { // db = Host.Services.GetService<QuartzDbContext>(); // listQuartzTask = db.QuartzTask.Where(w => w.IsDelete == 0 // && w.MachineName == machine // && w.InstanceId == QuartzOpt.InsatanceId) // .ToListAsync().GetAwaiter().GetResult(); // foreach (var item in listQuartzTask) // { // var jobKey = new JobKey(item.TaskName, item.GroupName); // var triggerKey = new TriggerKey(item.TaskName, item.GroupName); // // var jobItem = db.QuartzTask.FirstOrDefault(w => w.IsDelete == 0 // // && w.TaskName == jobKey.Name // // && w.GroupName == jobKey.Group // // && w.MachineName == machine // // && w.InstanceId == scheduler.SchedulerInstanceId); // // item.Status = (int)TaskStatus.Faulted; // // item.OperateStatus = (int)OperateStatus.Stop; // // db.Update<QuartzTask>(jobItem); // // db.SaveChanges(); // if (scheduler.CheckExists(jobKey).Result) // { // var triggerListener = scheduler.ListenerManager.GetTriggerListener("triggerUpdate"); // if (triggerListener == null) // { // triggerListener = new TriggerUpdateListens(); // IMatcher<TriggerKey> triggermatcher = KeyMatcher<TriggerKey>.KeyEquals(triggerKey); // scheduler.ListenerManager.AddTriggerListener(triggerListener, triggermatcher); // } // var jobListener = scheduler.ListenerManager.GetJobListener("jobupdateListens"); // if (jobListener == null) // { // IJobListener jobUpdateListener = new JobUpdateListens(); // IMatcher<JobKey> jobmatcher = KeyMatcher<JobKey>.KeyEquals(jobKey); // scheduler.ListenerManager.AddJobListener(jobUpdateListener, jobmatcher); // } // } // } //} return(scheduler); // Tell quartz to schedule the job using our trigger //await scheduler.ScheduleJob(job, trigger); } catch (SchedulerException sep) { log.Log(Microsoft.Extensions.Logging.LogLevel.Error, 0, sep, "job执行错误。"); } return(null); }
public Task TriggerFired(ITrigger trigger, IJobExecutionContext context, CancellationToken cancellationToken = default(CancellationToken)) { ILoggerFactory loggerFact = Program.Host.Services.GetService <ILoggerFactory>(); var _logger = loggerFact.CreateLogger <ZookeeperService>(); _logger.LogInformation(0, null, "开始执行job.name:{0} group:{1}", context.JobDetail.Key.Name, context.JobDetail.Key.Group); string machine = Environment.MachineName; try { var customerAttri = context.JobDetail.JobType.GetCustomAttributes(false); foreach (var customer in customerAttri) { if (customer is DistributingAttributes) { var distri = customer as DistributingAttributes; var zookeeper = Program.Host.Services.GetService <IZookeeperService>(); string currentTempNodeName = string.Empty; string fullPath = "/lock/" + context.JobDetail.Key.Name + context.JobDetail.Key.Group; int flag = 0; //Repeat: string jsonData = zookeeper.GetDataByLockNode(fullPath, "getlock" , ZooDefs.Ids.OPEN_ACL_UNSAFE, out currentTempNodeName); if (string.IsNullOrEmpty(currentTempNodeName)) { _logger.LogError("获取锁失败。节点:{0},锁前缀:{1},重试:{2}", fullPath, "getlock", flag); // if(flag<=2) // { // flag = flag + 1; // goto Repeat; // } VoteJob = true; _logger.LogError("获取分片失败,取消job执行,等待下次。"); return(Task.FromResult(false)); //context.Scheduler.Interrupt(context.JobDetail.Key); } QuartzDbContext db = Program.Host.Services.GetService <QuartzDbContext>(); var item = db.QuartzTask.Where(w => w.IsDelete == 0 && w.TaskName == context.JobDetail.Key.Name && w.GroupName == context.JobDetail.Key.Group && w.MachineName == machine && w.InstanceId == context.Scheduler.SchedulerInstanceId).FirstOrDefault(); if (item != null) { //TODO 这里可以找出机器名,拼接处api,可以查看主机是否存活,从而将一些挂起的任务重新分配。 } string distributeFlag = item.MachineName + item.InstanceId; List <DistributingData> distriData = new List <DistributingData>(); DistributingData currentDistriEntity = new DistributingData(); if (string.IsNullOrEmpty(jsonData)) { currentDistriEntity = new DistributingData { DistributeFlag = distributeFlag, PageIndex = 1, PageSize = Program.QuartzOpt.CustomerRecordCountForTest //配置 }; distriData.Add(currentDistriEntity); } else { distriData = Newtonsoft.Json.JsonConvert.DeserializeObject <List <DistributingData> >(jsonData); if (distriData == null || distriData.Count() < 1) { currentDistriEntity = new DistributingData { DistributeFlag = distributeFlag, PageIndex = 1, PageSize = Program.QuartzOpt.CustomerRecordCountForTest //配置 }; distriData.Add(currentDistriEntity); } else { currentDistriEntity = distriData.Where(w => w.DistributeFlag == distributeFlag).SingleOrDefault(); if (currentDistriEntity == null) { var maxPageIndex = distriData.Max(w => w.PageIndex); maxPageIndex = maxPageIndex + 1; var entity = new DistributingData { DistributeFlag = distributeFlag, PageIndex = maxPageIndex, PageSize = Program.QuartzOpt.CustomerRecordCountForTest //配置 }; distriData.Add(entity); } else { var maxPageIndex = distriData.Max(w => w.PageIndex); maxPageIndex = maxPageIndex + 1; currentDistriEntity.PageIndex = maxPageIndex; } } } item.Remark = Newtonsoft.Json.JsonConvert.SerializeObject(currentDistriEntity); db.Update(item); db.SaveChanges(); string resultData = Newtonsoft.Json.JsonConvert.SerializeObject(distriData); context.JobDetail.JobDataMap.Put("distriData", currentDistriEntity); zookeeper.SetDataAsync(fullPath , resultData, false).GetAwaiter().GetResult(); zookeeper.DeleteNode(currentTempNodeName); _logger.LogInformation("分片执行:{0}", resultData); } } } catch (ConnectionLossException cle) { VoteJob = true; _logger.LogError(cle, "获取同步锁出现错误。连接丢失"); } catch (SessionExpiredException sep) { VoteJob = true; _logger.LogError(sep, "获取同步锁出现错误。连接过期"); } catch (KeeperException kep) { VoteJob = true; _logger.LogError(kep, "获取同步锁出现错误。操作zookeeper出错"); } catch (Exception ep) { try { _logger.LogError(0, ep, "分片失败。"); //context.Scheduler.DeleteJob(context.JobDetail.Key).GetAwaiter().GetResult(); VoteJob = true; QuartzDbContext db = Program.Host.Services.GetService <QuartzDbContext>(); var item = db.QuartzTask.Where(w => w.IsDelete == 0 && w.TaskName == context.JobDetail.Key.Name && w.GroupName == context.JobDetail.Key.Group && w.MachineName == machine && w.InstanceId == context.Scheduler.SchedulerInstanceId).FirstOrDefault(); if (item == null) { _logger.LogError(0, ep, "分片失败,获取数据库记录失败。"); } else { item.Status = (int)TaskStatus.Canceled; item.OperateStatus = (int)OperateStatus.Stop; item.Remark = ep.ToString(); db.Update(item); db.SaveChanges(); } } catch (Exception eep) { _logger.LogError(0, eep, "分片失败,更新数据库失败。"); } } return(Task.FromResult(true)); }