/// <summary> /// 添加后台作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public string AddHttpbackgroundjob(HttpJobItem jobItem) { try { var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName; if (string.IsNullOrEmpty(queueName)) { queueName = EnqueuedState.DefaultQueue; } if (!string.IsNullOrEmpty(jobItem.RunAt)) { //如果设置了 指定的运行时间 先parse一下 if (DateTimeOffset.TryParse(jobItem.RunAt, out var runAtTime)) { return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), runAtTime)); } } if (jobItem.DelayFromMinutes <= 0) { return(BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null))); } return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes))); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex); return(null); } }
/// <summary> /// signalR推送使用 /// </summary> /// <param name="url"></param> /// <param name="data"></param> /// <param name="statuscode"></param> /// <returns></returns> public static string SendRequest(string url, string data) { var item = new HttpJobItem() { Data = "{" + $"\"message\":\"{data}\"" + "}", Url = url, Method = "post", ContentType = "application/json" }; var client = GetHttpClient(item); var httpMesage = PrepareHttpRequestMessage(item); _ = client.SendAsync(httpMesage).GetAwaiter().GetResult(); var httpcontent = new StringContent(item.Data.ToString()); client.DefaultRequestHeaders.Add("Method", "Post"); httpcontent.Headers.ContentType = new MediaTypeHeaderValue(item.ContentType); client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"); client.DefaultRequestHeaders.Add("KeepAlive", "false"); _ = client.PostAsync(item.Url, httpcontent).GetAwaiter().GetResult(); string result = httpcontent.ReadAsStringAsync().GetAwaiter().GetResult(); return(result); }
public static void Excute(HttpJobItem item, string jobName = null, string queuename = null, bool isretry = false, PerformContext context = null) { try { //此处信息会显示在执行结果日志中 context.SetTextColor(ConsoleTextColor.Yellow); context.WriteLine($"任务开始执行,执行时间{DateTime.Now.ToString()}"); context.WriteLine($"任务名称:{jobName}"); context.WriteLine($"参数:{JsonConvert.SerializeObject(item)}"); var client = GetHttpClient(item); var httpMesage = PrepareHttpRequestMessage(item); var httpResponse = new HttpResponseMessage(); httpResponse = SendUrlRequest(item, client, httpMesage); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); context.WriteLine($"执行结果:{result}"); } catch (Exception ex) { //获取重试次数 var count = context.GetJobParameter <string>("RetryCount"); context.SetTextColor(ConsoleTextColor.Red); //signalR推送 //SendRequest(UseApollo?ConfigSettings.Instance.ServiceAddress:ConfigSettings.Instance.URL+"/api/Publish/EveryOne", "测试"); if (count == "3" && ConfigSettings.Instance.UseEmail)//重试达到三次的时候发邮件通知 { SendEmail(item.JobName, item.Url, ex.ToString()); } logger.Error(ex, "HttpJob.Excute"); context.WriteLine($"执行出错:{ex.Message}"); throw;//不抛异常不会执行重试操作 } }
public static HttpClient GetHttpClient(HttpJobItem item) { var handler = new HttpClientHandler(); if (HangfireHttpJobOptions.Proxy == null) { handler.UseProxy = false; } else { handler.Proxy = HangfireHttpJobOptions.Proxy; } var HttpClient = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(item.Timeout == 0 ? HangfireHttpJobOptions.GlobalHttpTimeOut : item.Timeout), }; if (!string.IsNullOrEmpty(item.BasicUserName) && !string.IsNullOrEmpty(item.BasicPassword)) { var byteArray = Encoding.ASCII.GetBytes(item.BasicUserName + ":" + item.BasicPassword); HttpClient.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); } return(HttpClient); }
/// <summary> /// 执行job /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public bool StartBackgroudJob(HttpJobItem jobItem) { try { if (string.IsNullOrEmpty(jobItem.Data)) { return(true); } using (var connection = JobStorage.Current.GetConnection()) { var hashKey = CodingUtil.MD5(jobItem.JobName + ".runtime"); using (var tran = connection.CreateWriteTransaction()) { tran.SetRangeInHash(hashKey, new List <KeyValuePair <string, string> > { new KeyValuePair <string, string>("Data", jobItem.Data) }); tran.Commit(); } } return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.StartBackgroudJob", ex); return(false); } }
private static void SendFailMail(HttpJobItem item, string result, Exception exception) { try { if (!item.SendFaiMail) { return; } var mail = string.IsNullOrEmpty(item.Mail) ? string.Join(",", HangfireHttpJobOptions.MailOption.AlertMailList) : item.Mail; if (string.IsNullOrWhiteSpace(mail)) { return; } var subject = $"【JOB】[Fail]" + item.JobName; result = result.Replace("\n", "<br/>"); result = result.Replace("\r\n", "<br/>"); if (exception != null) { result += BuildExceptionMsg(exception); } EmailService.Instance.Send(mail, subject, result); } catch (Exception ex) { Logger.ErrorException("HttpJob.SendFailMail=>" + item, ex); } }
/// <summary> /// 添加周期性作业 /// </summary> /// <param name="jobItem"></param> /// <param name="timeZone">job 时区信息</param> /// <returns></returns> public bool AddHttprecurringjob(HttpJobItem jobItem) { if (string.IsNullOrEmpty(jobItem.QueueName)) { jobItem.QueueName = EnqueuedState.DefaultQueue; } else { //get queues from server // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault(); // ReSharper disable once PossibleNullReferenceException var queues = server.Queues.ToList(); if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0) { Logger.Warn($"HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!"); } } var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName; if (string.IsNullOrEmpty(queueName)) { queueName = EnqueuedState.DefaultQueue; } try { // 先用每个job配置的 如果没有就用系统配置的 在没有就用Local TimeZoneInfo timeZone = null; if (!string.IsNullOrEmpty(jobItem.TimeZone)) { timeZone = TimeZoneInfoHelper.OlsonTimeZoneToTimeZoneInfo(jobItem.TimeZone); } if (timeZone == null) { timeZone = CodingUtil.HangfireHttpJobOptions.RecurringJobTimeZone ?? TimeZoneInfo.Local; } if (string.IsNullOrEmpty(jobItem.Cron)) { //支持添加一个 只能手动出发的 RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never, timeZone, jobItem.QueueName.ToLower()); return(true); } RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), jobItem.Cron, timeZone, jobItem.QueueName.ToLower()); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return(false); } }
/// <summary> /// 添加周期性作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public bool AddHttprecurringjob(HttpJobItem jobItem) { try { RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, null), jobItem.Corn, TimeZoneInfo.Local); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return(false); } }
/// <summary> /// 添加后台作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public bool AddHttpbackgroundjob(HttpJobItem jobItem) { try { BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, jobItem.QueueName, jobItem.IsRetry, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes)); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex); return(false); } }
/// <summary> /// 添加后台作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public string AddHttpbackgroundjob(HttpJobItem jobItem) { try { if (string.IsNullOrEmpty(jobItem.QueueName)) { jobItem.QueueName = EnqueuedState.DefaultQueue; } else { //get queues from server // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault(); // ReSharper disable once PossibleNullReferenceException if (server == null) { return("active server not exist!"); } var queues = server.Queues.Select(m => m.ToLower()).ToList(); if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0) { Logger.Warn($"HttpJobDispatcher.AddHttpbackgroundjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!"); jobItem.QueueName = EnqueuedState.DefaultQueue; } } if (!string.IsNullOrEmpty(jobItem.RunAt)) { //如果设置了 指定的运行时间 先parse一下 if (DateTimeOffset.TryParse(jobItem.RunAt, out var runAtTime)) { return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, null, null, false, null), runAtTime)); } } if (jobItem.DelayFromMinutes <= 0) { return(BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, null, null, false, null))); } return(BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, null, null, false, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes))); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex); return(null); } }
public static HttpRequestMessage PrepareHttpRequestMessage(HttpJobItem item) { var request = new HttpRequestMessage(new HttpMethod(item.Method), item.Url); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(item.ContentType)); if (!item.Method.ToLower().Equals("get")) { if (!string.IsNullOrEmpty(item.Data)) { var bytes = Encoding.UTF8.GetBytes(item.Data); request.Content = new ByteArrayContent(bytes, 0, bytes.Length); } } return(request); }
private static HttpRequestMessage PrepareHttpRequestMessage(HttpJobItem item, PerformContext context) { var request = new HttpRequestMessage(new HttpMethod(item.Method), item.Url); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(item.ContentType)); if (!item.Method.ToLower().Equals("get")) { if (!string.IsNullOrEmpty(item.Data)) { //var bytes = Encoding.UTF8.GetBytes(item.Data); request.Content = new StringContent(item.Data, Encoding.UTF8, item.ContentType); //request.Content = new ByteArrayContent(bytes, 0, bytes.Length); } } if (!string.IsNullOrEmpty(item.AgentClass)) { request.Headers.Add("x-job-agent-class", item.AgentClass); var consoleInfo = GetConsoleInfo(context); if (consoleInfo != null) { request.Headers.Add("x-job-agent-console", JsonConvert.SerializeObject(consoleInfo)); } } if (context != null) { context.Items.TryGetValue("Action", out var actionItem); var action = actionItem as string; if (!string.IsNullOrEmpty(action)) { request.Headers.Add("x-job-agent-action", action); } else if (!string.IsNullOrEmpty(item.AgentClass)) { request.Headers.Add("x-job-agent-action", "run"); } } if (!string.IsNullOrEmpty(item.BasicUserName) && !string.IsNullOrEmpty(item.BasicPassword)) { var byteArray = Encoding.ASCII.GetBytes(item.BasicUserName + ":" + item.BasicPassword); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); } return(request); }
public static HttpRequestMessage PrepareHttpRequestMessage(HttpJobItem item) { var request = new HttpRequestMessage(new HttpMethod(item.Method), item.Url); request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(item.ContentType)); if (!item.Method.ToLower().Equals("get")) { if (!string.IsNullOrEmpty(item.Data)) { var content = new StringContent(item.Data); content.Headers.ContentType = new MediaTypeWithQualityHeaderValue(item.ContentType); request.Content = content; } } return(request); }
public static void Excute(HttpJobItem item, string jobName = null, PerformContext context = null) { try { //此处信息会显示在执行结果日志中 context.SetTextColor(ConsoleTextColor.Yellow); context.WriteLine($"任务开始执行,执行时间{DateTime.Now.ToString()}"); context.WriteLine($"任务名称:{jobName}"); context.WriteLine($"参数:{JsonConvert.SerializeObject(item)}"); var client = GetHttpClient(item); var httpMesage = PrepareHttpRequestMessage(item); var httpResponse = new HttpResponseMessage(); if (item.Method.ToLower() == "post") { var httpcontent = new StringContent(item.Data.ToString()); client.DefaultRequestHeaders.Add("Method", "Post"); httpcontent.Headers.ContentType = new MediaTypeHeaderValue(item.ContentType); client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"); client.DefaultRequestHeaders.Add("KeepAlive", "false"); httpResponse = client.PostAsync(item.Url, httpcontent).GetAwaiter().GetResult(); } else { httpResponse = client.SendAsync(httpMesage).GetAwaiter().GetResult(); } HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); context.WriteLine($"执行结果:{result}"); } catch (Exception ex) { //获取重试次数 var count = context.GetJobParameter <string>("RetryCount"); context.SetTextColor(ConsoleTextColor.Red); //signalR推送 //SendRequest(ConfigSettings.Instance.URL+"/api/Publish/EveryOne", "测试"); if (count == "3")//重试达到三次的时候发邮件通知 { SendEmail(item.JobName, item.Url, ex.ToString()); } logger.Error(ex, "HttpJob.Excute"); context.WriteLine($"执行出错:{ex.Message}"); throw;//不抛异常不会执行重试操作 } }
/// <summary> /// 删除周期性job /// </summary> /// <param name="jobItem"></param> /// <returns></returns> private bool DelJob(HttpJobItem jobItem) { try { if (!string.IsNullOrEmpty(jobItem.Data) && jobItem.Data == "backgroundjob") { return(BackgroundJob.Delete(jobItem.JobName)); } RecurringJob.RemoveIfExists(jobItem.JobName); return(true); } catch (Exception) { return(false); } }
/// <summary> /// 添加周期性作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public bool AddHttprecurringjob(HttpJobItem jobItem) { if (string.IsNullOrEmpty(jobItem.QueueName)) { jobItem.QueueName = "DEFAULT"; } else { //get queues from server // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault(); // ReSharper disable once PossibleNullReferenceException var queues = server.Queues.ToList(); if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0) { Logger.Warn("HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName not exist, Use DEFAULT extend!"); } } var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName; if (string.IsNullOrEmpty(queueName)) { queueName = "DEFAULT"; } try { //支持添加一个 只能手动出发的 if (string.IsNullOrEmpty(jobItem.Cron)) { RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), Cron.Never, TimeZoneInfo.Local, jobItem.QueueName.ToLower()); return(true); } RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), jobItem.Cron, TimeZoneInfo.Local, jobItem.QueueName.ToLower()); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return(false); } }
public virtual ReturnMsg AddOrUpdateRecurringJob(Hangfire.HttpJob.Server.HttpJobItem httpJob) { try { RecurringJob.AddOrUpdate(httpJob.JobName, () => Hangfire.HttpJob.Server.HttpJob.Excute(httpJob, httpJob.JobName, httpJob.QueueName, httpJob.IsRetry, null), httpJob.Corn, TimeZoneInfo.Local); } catch (Exception ec) { return(new ReturnMsg() { Errorcode = "0", Message = $"添加周期任务失败,{ec.Message}" }); } return(new ReturnMsg() { Errorcode = "1", Message = "添加周期任务成功!!" }); }
public static void Excute(HttpJobItem item, string jobName = null, PerformContext context = null) { try { context.WriteLine(jobName); context.WriteLine(JsonConvert.SerializeObject(item)); var client = GetHttpClient(item); var httpMesage = PrepareHttpRequestMessage(item); var httpResponse = client.SendAsync(httpMesage).GetAwaiter().GetResult(); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); context.WriteLine(result); } catch (Exception ex) { Logger.ErrorException("HttpJob.Excute", ex); context.WriteLine(ex.Message); } }
public virtual ReturnMsg AddBackGroundJob(Hangfire.HttpJob.Server.HttpJobItem httpJob) { var addreslut = string.Empty; try { addreslut = BackgroundJob.Enqueue(() => Hangfire.HttpJob.Server.HttpJob.Excute(httpJob, httpJob.JobName, httpJob.QueueName, httpJob.IsRetry, null)); } catch (Exception ec) { return(new ReturnMsg() { Errorcode = "0", Message = $"添加队列任务失败,{ec.Message}" }); } return(new ReturnMsg() { Errorcode = "1", Message = "添加队列任务成功!!" }); }
public virtual ReturnMsg AddScheduleJob(Hangfire.HttpJob.Server.HttpJobItem httpJob) { var reslut = string.Empty; try { reslut = BackgroundJob.Schedule(() => Hangfire.HttpJob.Server.HttpJob.Excute(httpJob, httpJob.JobName, httpJob.QueueName, httpJob.IsRetry, null), TimeSpan.FromMinutes(httpJob.DelayFromMinutes)); } catch (Exception ec) { return(new ReturnMsg() { Errorcode = "0", Message = $"添加延迟任务失败,{ec.Message}" }); } return(new ReturnMsg() { Errorcode = "1", Message = "添加延迟任务成功!!" }); }
public bool AddHttpbackgroundjob(HttpJobItem jobItem) { try { // 普通作业 // 单纯的httpjob 有设置延迟 // 单纯的httpjob 没有设置延迟 但是不可以不设置延迟 所以就设置一个非常大的延迟 比如100年后 // 以agent模式开发的job 有设置延迟 // 以agent模式开发的job 没有设置延迟 // 没有设置延迟 代表的只可以自己触发 var queueName = !string.IsNullOrEmpty(jobItem.AgentClass) ? "JobAgent" : jobItem.QueueName; if (string.IsNullOrEmpty(queueName)) { queueName = "DEFAULT"; } if (jobItem.DelayFromMinutes == -1) //约定 { //代表设置的是智能自己触发的延迟job var jobId = BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName + (!string.IsNullOrEmpty(jobItem.AgentClass) ? "| JobAgent |" : ""), "multiple", jobItem.EnableRetry, null), DateTimeOffset.Now.AddYears(100)); //自己触发完成后再把自己添加一遍 BackgroundJob.ContinueJobWith(jobId, () => AddHttpbackgroundjob(jobItem), JobContinuationOptions.OnAnyFinishedState); return(true); } if (jobItem.DelayFromMinutes == 0) { BackgroundJob.Enqueue(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null)); return(true); } BackgroundJob.Schedule(() => HttpJob.Excute(jobItem, jobItem.JobName, queueName, jobItem.EnableRetry, null), TimeSpan.FromMinutes(jobItem.DelayFromMinutes)); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttpbackgroundjob", ex); return(false); } }
/// <summary> /// 添加周期性作业 /// </summary> /// <param name="jobItem"></param> /// <returns></returns> public bool AddHttprecurringjob(HttpJobItem jobItem) { //get queues from server var server = JobStorage.Current.GetMonitoringApi().Servers(). Where(p => p.Queues.Count > 0).FirstOrDefault(); var queues = server.Queues.ToList(); if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0) { return(false); } try { RecurringJob.AddOrUpdate(jobItem.JobName, () => HttpJob.Excute(jobItem, jobItem.JobName, jobItem.QueueName, jobItem.IsRetry, null), jobItem.Corn, TimeZoneInfo.Local, jobItem.QueueName.ToLower()); return(true); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return(false); } }
/// <summary> /// 发送请求 /// </summary> /// <param name="item"></param> /// <param name="client"></param> /// <param name="httpMesage"></param> /// <returns></returns> private static HttpResponseMessage SendUrlRequest(HttpJobItem item, HttpClient client, HttpRequestMessage httpMesage) { HttpResponseMessage httpResponse; if (item.Method.ToLower() == "post") { var httpcontent = new StringContent(item.Data.ToString()); client.DefaultRequestHeaders.Add("Method", "Post"); httpcontent.Headers.ContentType = new MediaTypeHeaderValue(item.ContentType); client.DefaultRequestHeaders.Add("UserAgent", "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36"); client.DefaultRequestHeaders.Add("KeepAlive", "false"); httpResponse = client.PostAsync(item.Url, httpcontent).GetAwaiter().GetResult(); } else { httpResponse = client.SendAsync(httpMesage).GetAwaiter().GetResult(); } return(httpResponse); }
public static void Excute(HttpJobItem item, string jobName = null, PerformContext context = null) { try { //此处信息会显示在执行结果日志中 context.WriteLine("任务开始执行"); context.WriteLine($"{DateTime.Now.ToString()}"); context.WriteLine(jobName); context.WriteLine(JsonConvert.SerializeObject(item)); var client = GetHttpClient(item); var httpMesage = PrepareHttpRequestMessage(item); var httpResponse = client.SendAsync(httpMesage).GetAwaiter().GetResult(); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); context.WriteLine($"执行结果:{result}"); } catch (Exception ex) { Logger.ErrorException("HttpJob.Excute", ex); context.WriteLine($"执行出错:{ex.Message}"); } }
/// <summary> /// 获取AgentJob的运行详情 /// </summary> /// <param name="item"></param> /// <returns></returns> public static string GetAgentJobDetail(HttpJobItem item) { if (item.Timeout < 1) { item.Timeout = 5000; } HttpClient client; if (!string.IsNullOrEmpty(HangfireHttpJobOptions.Proxy)) { // per proxy per HttpClient client = HangfireHttpClientFactory.Instance.GetProxiedHttpClient(HangfireHttpJobOptions.Proxy); } else { //per host per HttpClient client = HangfireHttpClientFactory.Instance.GetHttpClient(item.Url); } var request = new HttpRequestMessage(new HttpMethod("Get"), item.Url); request.Headers.Add("x-job-agent-class", item.AgentClass); request.Headers.Add("x-job-agent-action", "detail"); if (!string.IsNullOrEmpty(item.BasicUserName) && !string.IsNullOrEmpty(item.BasicPassword)) { var byteArray = Encoding.ASCII.GetBytes(item.BasicUserName + ":" + item.BasicPassword); request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); } var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout)); var httpResponse = client.SendAsync(request, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult(); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); return(result); }
public static void Excute(HttpJobItem item, string jobName = null, string queuename = null, bool isretry = false, PerformContext context = null) { var logList = new List <string>(); var result = false; try { object runTimeDataItem = null; context?.Items.TryGetValue("Data", out runTimeDataItem); if (runTimeDataItem != null) { var runTimeData = runTimeDataItem as string; if (!string.IsNullOrEmpty(runTimeData)) { item.Data = runTimeData; } } if (Run(item, context, logList)) { SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList)); result = true; } else { SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), null); } } catch (Exception ex) { var statusCodeEx = ex as HttpStatusCodeException; RunWithTry(() => context.SetTextColor(ConsoleTextColor.Red)); Logger.ErrorException("HttpJob.Excute=>" + item, ex); if (statusCodeEx != null && statusCodeEx.IsEl) { RunWithTry(() => context.WriteLine($"【{Strings.CallbackELExcuteResult}:Fail 】" + statusCodeEx.El)); } else { RunWithTry(() => context.WriteLine(ex.ToString())); } if (!item.EnableRetry) { if (item.Fail != null) { item.Fail.CallbackRoot = item.JobName + ".Fail"; item.Cron = statusCodeEx == null || string.IsNullOrEmpty(statusCodeEx.Msg) ? ex.Message : statusCodeEx.Msg; if (Run(item.Fail, context, logList, item)) { SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList)); return; } } SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), ex); AddErrToJob(context, ex); throw; } //获取重试次数 var count = RunWithTry <string>(() => context.GetJobParameter <string>("RetryCount")) ?? string.Empty; if (count == "3") //重试达到三次的时候发邮件通知 { if (item.Fail != null) { item.Fail.CallbackRoot = item.JobName + ".Fail"; item.Cron = statusCodeEx == null || string.IsNullOrEmpty(statusCodeEx.Msg) ? ex.Message : statusCodeEx.Msg; if (Run(item.Fail, context, logList, item)) { SendSuccess(context.BackgroundJob.Id, item, string.Join("<br/>", logList)); return; } } RunWithTry(() => context.WriteLine(Strings.LimitReached)); logList.Add(Strings.LimitReached); SendFail(context.BackgroundJob.Id, item, string.Join("<br/>", logList), ex); AddErrToJob(context, ex); return; } context?.Items.Add("RetryCount", count); throw; } if (!result) { throw new CallbackJobException("Callback job Fail"); } }
/// <summary> /// Run HttpRequest /// </summary> /// <param name="item"></param> /// <param name="context"></param> /// <param name="logList"></param> /// <param name="parentJob"></param> /// <exception cref="HttpStatusCodeException"></exception> private static bool Run(HttpJobItem item, PerformContext context, List <string> logList, HttpJobItem parentJob = null) { CancellationTokenSource cancelToken = null; try { if (parentJob != null) { RunWithTry(() => context.SetTextColor(ConsoleTextColor.Green)); if (item.Timeout < 1) { item.Timeout = parentJob.Timeout; } if (item.Data.Contains("@parent@")) { item.Data = item.Data.Replace("@parent@", parentJob.Cron); } if (string.IsNullOrEmpty(item.BasicUserName)) { item.BasicUserName = parentJob.BasicUserName; } if (string.IsNullOrEmpty(item.BasicPassword)) { item.BasicPassword = parentJob.BasicPassword; } if (item.Headers == null || !item.Headers.Any()) { item.Headers = parentJob.Headers; } if (string.IsNullOrEmpty(item.QueueName)) { item.QueueName = parentJob.QueueName; } RunWithTry(() => context.WriteLine($"【{Strings.CallbackStart}】[{item.CallbackRoot}]")); item.JobName = item.CallbackRoot; } else { if (string.IsNullOrEmpty(item.CallbackRoot)) { item.CallbackRoot = item.JobName; } if (item.Timeout < 1) { item.Timeout = 5000; } RunWithTry(() => context.SetTextColor(ConsoleTextColor.Yellow)); } RunWithTry(() => context.WriteLine($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}")); logList.Add($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); RunWithTry(() => context.WriteLine($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT" : item.QueueName)}")); logList.Add( $"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{(string.IsNullOrEmpty(item.QueueName) ? "DEFAULT" : item.QueueName)}"); RunWithTry(() => context.WriteLine($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item)}】")); logList.Add($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item, Formatting.Indented)}】"); HttpClient client; //当前job指定如果开启了proxy 并且 有配置代理 那么就走代理 if (CodingUtil.TryGetGlobalProxy(out var globalProxy) && item.Headers != null && item.Headers.TryGetValue("proxy", out var enableCurrentJobProxy) && !string.IsNullOrEmpty(enableCurrentJobProxy) && enableCurrentJobProxy.ToLower().Equals("true")) { // per proxy per HttpClient client = HangfireHttpClientFactory.Instance.GetProxiedHttpClient(globalProxy); RunWithTry(() => context.WriteLine($"Use Proxy:{globalProxy}")); logList.Add($"Proxy:{globalProxy}"); } else { //per host per HttpClient client = HangfireHttpClientFactory.Instance.GetHttpClient(item.Url); } var httpMesage = PrepareHttpRequestMessage(item, context, parentJob); cancelToken = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout)); var httpResponse = client.SendAsync(httpMesage, cancelToken.Token).ConfigureAwait(false).GetAwaiter().GetResult(); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode}")); logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode}"); RunWithTry(() => context.WriteLine($"{Strings.JobResult}:{result}")); logList.Add($"{Strings.JobResult}:{result}"); RunWithTry(() => context.WriteLine($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}")); logList.Add($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); //如果agent那边调度报错 if (!string.IsNullOrEmpty(item.AgentClass)) { if (CodingUtil.HangfireHttpJobOptions.EnableJobAgentErrorThrow && httpResponse.StatusCode == HttpStatusCode.InternalServerError) { throw new AgentJobException(item.AgentClass, result); } //jobagent的单例没有执行完重复调度的case是否要作为异常 if (!CodingUtil.IgnoreJobAgentSingletonMultExcuteError() && httpResponse.StatusCode == HttpStatusCode.NotImplemented) { throw new AgentJobException(item.AgentClass, result); } //jobagent的话 在header里面有一个agentServerId GetCurrentJobAgentServerId(httpResponse, item, context); } //检查HttpResponse StatusCode else if ((CodingUtil.HangfireHttpJobOptions.CheckHttpResponseStatusCode == null && (int)httpResponse.StatusCode < 400) || (CodingUtil.HangfireHttpJobOptions.CheckHttpResponseStatusCode?.Invoke(httpResponse.StatusCode, result) ?? true)) { RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok ")); logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode} ===> CheckResult: Ok "); } else { //错误的log都会在exception里面出 throw new HttpStatusCodeException(httpResponse.StatusCode, result); } //检查是否有设置EL表达式 可以自定义检查StatusCode 和 解析返回的参数值 if (!string.IsNullOrEmpty(item.CallbackEL)) { var elResult = InvokeSpringElCondition(item.CallbackEL, result, context, new Dictionary <string, object> { { "resultBody", result }, { "StatusCode", (int)httpResponse.StatusCode } }); if (!elResult) { //错误的log都会在exception里面出 throw new HttpStatusCodeException(item.CallbackEL, result); } RunWithTry(() => context.WriteLine($"【{Strings.CallbackELExcuteResult}:Ok 】" + item.CallbackEL)); } if (parentJob != null) { RunWithTry(() => context.WriteLine($"【{Strings.CallbackSuccess}】[{item.CallbackRoot}]")); } //到这里查看是否有 子Job if (item.Success != null) { item.Cron = result; //父job的执行结果 item.Success.CallbackRoot = item.CallbackRoot + ".Success"; return(Run(item.Success, context, logList, item)); } return(true); }
/// <summary> /// 添加周期性作业 /// </summary> /// <returns></returns> public string AddHttprecurringjob(HttpJobItem jobItem, bool addOnly = false) { if (string.IsNullOrEmpty(jobItem.QueueName)) { jobItem.QueueName = EnqueuedState.DefaultQueue; } else { //get queues from server // ReSharper disable once ReplaceWithSingleCallToFirstOrDefault var server = JobStorage.Current.GetMonitoringApi().Servers().Where(p => p.Queues.Count > 0).FirstOrDefault(); // ReSharper disable once PossibleNullReferenceException if (server == null) { return("active server not exist!"); } var queues = server.Queues.Select(m => m.ToLower()).ToList(); if (!queues.Exists(p => p == jobItem.QueueName.ToLower()) || queues.Count == 0) { Logger.Warn($"HttpJobDispatcher.AddHttprecurringjob Error => HttpJobItem.QueueName:`{jobItem.QueueName}` not exist, Use DEFAULT extend!"); jobItem.QueueName = EnqueuedState.DefaultQueue; } } try { // 先用每个job配置的 如果没有就用系统配置的 在没有就用Local TimeZoneInfo timeZone = null; if (!string.IsNullOrEmpty(jobItem.TimeZone)) { timeZone = TimeZoneInfoHelper.OlsonTimeZoneToTimeZoneInfo(jobItem.TimeZone); } //https://github.com/yuzd/Hangfire.HttpJob/issues/78 var jobidentifier = string.IsNullOrEmpty(jobItem.RecurringJobIdentifier) ? jobItem.JobName : jobItem.RecurringJobIdentifier; if (addOnly) { using (var connection = JobStorage.Current.GetConnection()) { var existItem = connection.GetAllEntriesFromHash("recurring-job:" + jobidentifier); if (existItem != null && existItem.Count > 0) { return(jobidentifier + "is registerd!"); } } } if (timeZone == null) { timeZone = TimeZoneInfo.Local; } if (string.IsNullOrEmpty(jobItem.Cron)) { //支持添加一个 只能手动出发的 RecurringJob.AddOrUpdate(jobidentifier, () => HttpJob.Excute(jobItem, null, null, false, null), Cron.Never, timeZone, jobItem.QueueName.ToLower()); return(string.Empty); } RecurringJob.AddOrUpdate(jobidentifier, () => HttpJob.Excute(jobItem, null, null, false, null), jobItem.Cron, timeZone, jobItem.QueueName.ToLower()); return(string.Empty); } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.AddHttprecurringjob", ex); return(ex.Message); } }
/// <summary> /// 获取常规作业的jobAgent类型的JobInfo /// </summary> /// <param name="jobItem"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> private JobDetailInfo GetBackGroundJobDetail(HttpJobItem jobItem) { var result = new JobDetailInfo(); var jobName = string.Empty; try { using (var connection = JobStorage.Current.GetConnection()) { Job job = null; if (string.IsNullOrEmpty(jobItem.Cron)) { var jobData = connection.GetJobData(jobItem.JobName); if (jobData == null) { result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName; return(result); } job = jobData.Job; } else { Dictionary <string, string> dictionary = connection.GetAllEntriesFromHash("recurring-job:" + jobItem.JobName); if (dictionary == null || dictionary.Count == 0) { result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName; return(result); } if (!dictionary.TryGetValue(nameof(Job), out var jobDetail)) { result.Info = "GetJobDetail Error:can not found job by id:" + jobItem.JobName; return(result); } job = InvocationData.DeserializePayload(jobDetail).DeserializeJob(); } var jobItem2 = job.Args.FirstOrDefault(); var httpJobItem = jobItem2 as HttpJobItem; if (httpJobItem == null) { result.Info = $"GetJobDetail Error:jobData can not found job by id:" + jobItem.JobName; return(result); } result.JobName = jobName = httpJobItem.JobName; if (string.IsNullOrEmpty(httpJobItem.AgentClass)) { result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} Error:is not AgentJob! "; return(result); } var jobInfo = HttpJob.GetAgentJobDetail(httpJobItem); if (string.IsNullOrEmpty(jobInfo)) { result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} Error:get null info! "; return(result); } jobInfo = jobInfo.Replace("\r\n", "<br/>"); result.Info = jobInfo; return(result); } } catch (Exception ex) { Logger.ErrorException("HttpJobDispatcher.GetBackGroundJobDetail", ex); result.Info = $"{(!string.IsNullOrEmpty(jobName) ? "【" + jobName + "】" : string.Empty)} GetJobDetail Error:" + ex.ToString(); return(result); } }
public static void Excute(HttpJobItem item, string jobName = null, string queuename = null, bool isretry = false, PerformContext context = null) { var logList = new List <string>(); try { if (context == null) { return; } context.Items.TryGetValue("Data", out var runTimeDataItem); var runTimeData = runTimeDataItem as string; if (!string.IsNullOrEmpty(runTimeData)) { item.Data = runTimeData; } if (item.Timeout < 1) { item.Timeout = 5000; } RunWithTry(() => context.SetTextColor(ConsoleTextColor.Yellow)); RunWithTry(() => context.WriteLine($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}")); logList.Add($"{Strings.JobStart}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); RunWithTry(() => context.WriteLine($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{queuename ?? "DEFAULT"}")); logList.Add($"{Strings.JobName}:{item.JobName ?? string.Empty}|{Strings.QueuenName}:{queuename ?? "DEFAULT"}"); RunWithTry(() => context.WriteLine($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item)}】")); logList.Add($"{Strings.JobParam}:【{JsonConvert.SerializeObject(item, Formatting.Indented)}】"); HttpClient client; if (!string.IsNullOrEmpty(HangfireHttpJobOptions.Proxy)) { // per proxy per HttpClient client = HangfireHttpClientFactory.Instance.GetProxiedHttpClient(HangfireHttpJobOptions.Proxy); RunWithTry(() => context.WriteLine($"Proxy:{HangfireHttpJobOptions.Proxy}")); logList.Add($"Proxy:{HangfireHttpJobOptions.Proxy}"); } else { //per host per HttpClient client = HangfireHttpClientFactory.Instance.GetHttpClient(item.Url); } var httpMesage = PrepareHttpRequestMessage(item, context); var cts = new CancellationTokenSource(TimeSpan.FromMilliseconds(item.Timeout)); var httpResponse = client.SendAsync(httpMesage, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult(); HttpContent content = httpResponse.Content; string result = content.ReadAsStringAsync().GetAwaiter().GetResult(); RunWithTry(() => context.WriteLine($"{Strings.ResponseCode}:{httpResponse.StatusCode}")); logList.Add($"{Strings.ResponseCode}:{httpResponse.StatusCode}"); RunWithTry(() => context.WriteLine($"{Strings.JobResult}:{result}")); logList.Add($"{Strings.JobResult}:{result}"); RunWithTry(() => context.WriteLine($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}")); logList.Add($"{Strings.JobEnd}:{DateTime.Now:yyyy-MM-dd HH:mm:ss}"); SendSuccessMail(item, string.Join("<br/>", logList)); } catch (Exception ex) { RunWithTry(() => context.SetTextColor(ConsoleTextColor.Red)); Logger.ErrorException("HttpJob.Excute=>" + item, ex); RunWithTry(() => context.WriteLine(ex.ToString())); if (!item.EnableRetry) { SendFailMail(item, string.Join("<br/>", logList), ex); AddErrToJob(context, ex); return; } //获取重试次数 var count = RunWithTry <string>(() => context.GetJobParameter <string>("RetryCount")) ?? string.Empty; if (count == "3")//重试达到三次的时候发邮件通知 { SendFailMail(item, string.Join("<br/>", logList), ex); AddErrToJob(context, ex); return; } context.Items.Add("RetryCount", count); throw; } }