All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.hengboy.job.schedule.runnable.MicroJobExecuteRunnable Maven / Gradle / Ivy

There is a newer version: 0.0.3.RELEASE
Show newest version
/*
 *    Copyright [2019] [恒宇少年 - 于起宇]
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.github.hengboy.job.schedule.runnable;

import com.alibaba.fastjson.JSON;
import com.github.hengboy.job.core.enums.JobExecuteStatusEnum;
import com.github.hengboy.job.core.enums.LoadBalanceStrategy;
import com.github.hengboy.job.core.http.MicroJobRestTemplate;
import com.github.hengboy.job.core.http.RestUrlConstants;
import com.github.hengboy.job.core.http.RestUrlTools;
import com.github.hengboy.job.core.model.execute.JobExecuteParam;
import com.github.hengboy.job.core.model.execute.JobExecuteResult;
import com.github.hengboy.job.core.strategy.LbStrategy;
import com.github.hengboy.job.core.strategy.LbStrategyFactory;
import com.github.hengboy.job.schedule.quartz.QuartzJobContext;
import com.github.hengboy.job.schedule.queue.bean.JobQueueBean;
import com.github.hengboy.job.schedule.resource.MicroJobScheduleResource;
import lombok.AllArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;

/**
 * 任务执行线程
 *
 * @author:恒宇少年 - 于起宇
 * 

* DateTime:2019-01-31 13:12 * Blog:http://blog.yuqiyu.com * WebSite:http://www.jianshu.com/u/092df3f77bca * Gitee:https://gitee.com/hengboy * GitHub:https://github.com/hengyuboy */ @AllArgsConstructor public class MicroJobExecuteRunnable implements Runnable { /** * logger instance */ static Logger logger = LoggerFactory.getLogger(MicroJobExecuteRunnable.class); /** * 本次任务执行的对象 */ private JobQueueBean jobQueueBean; @Override public void run() { try { // 获取负载方式的实现 LbStrategy lbStrategy = LbStrategyFactory.getStrategy(LoadBalanceStrategy.valueOf(jobQueueBean.getLbStrategy())); // 初始化参与负载的节点 lbStrategy.initJoinNodes(MicroJobScheduleResource.getAllConsumerLbNode()); // 不同负载方式获取到的负载任务节点不同 String loadBalanceConsumerAddress = lbStrategy.select(jobQueueBean.getJobQueueKey()); if (loadBalanceConsumerAddress != null) { logger.info("Use Node:[{}] execute job [{}]", loadBalanceConsumerAddress, jobQueueBean.getJobQueueKey()); // 远程执行实例 MicroJobRestTemplate restTemplate = MicroJobScheduleResource.getRestTemplate(); // 任务执行参数 JobExecuteParam jobExecuteParam = new JobExecuteParam(jobQueueBean.getJobKey(), jobQueueBean.getJobQueueId(), jobQueueBean.getJobExecuteParam()); // 处理消费者地址 String[] consumerAddress = loadBalanceConsumerAddress.split(":"); // 格式化请求路径 String executeJobUrl = RestUrlTools.formatter(consumerAddress[0], Integer.valueOf(consumerAddress[1]), RestUrlConstants.CONSUMER_EXECUTE_JOB_FULL_URL); // 执行任务 JobExecuteResult jobExecuteResult = restTemplate.postJsonEntity(executeJobUrl, JSON.toJSONString(jobExecuteParam), HttpHeaders.EMPTY, JobExecuteResult.class); // 任务执行完后逻辑 // 1. 回收 // 2. 成功 // 3. 更新执行详情 jobExecuteAfter(jobQueueBean, jobExecuteResult, loadBalanceConsumerAddress); } // 更新状态为重试 else { MicroJobScheduleResource.getJobStore().updateJobState(jobQueueBean.getExecuteLogId(), JobExecuteStatusEnum.RETRY.toString()); // 任务回收,放入重试队列 jobRecovery(jobQueueBean); } } catch (Exception e) { logger.error("Execute job :" + jobQueueBean.getJobQueueKey() + "error", e); jobRecovery(jobQueueBean); } } /** * 任务回收 * * @param jobQueueBean */ private void jobRecovery(JobQueueBean jobQueueBean) { try { MicroJobScheduleResource.JOB_RECOVERY_RETRY_QUEUE.put(jobQueueBean); if (jobQueueBean.getRetryCount() < MicroJobScheduleResource.getMaxRetryTimes()) { logger.warn("Job:[{}] recovery completion", jobQueueBean.getJobQueueKey()); } else { logger.error("Job:[{}] upper limit of retries , recovery ignore", jobQueueBean.getJobQueueKey()); } } catch (InterruptedException ex) { logger.info("Job:[{}] recovery error", jobQueueBean.getJobQueueKey()); ex.printStackTrace(); } } /** * 远程任务执行完成后 * 1. 回收 * 2. 成功 * 3. 更新执行详情 * * @param jobExecuteResult 远程执行结果 * @param jobQueueBean 任务执行详情 */ private void jobExecuteAfter(JobQueueBean jobQueueBean, JobExecuteResult jobExecuteResult, String loadBalanceConsumerAddress) { try { // 任务执行状态,默认成功 JobExecuteStatusEnum jobExecuteStatusEnum = JobExecuteStatusEnum.SUCCESS; switch (jobExecuteResult.getCode()) { case SUCCESS: // 更新成功时间 MicroJobScheduleResource.getJobStore().updateJobExecuteSuccessTime(jobQueueBean.getExecuteLogId()); break; case ERROR: case RETRY: // 更新状态为重试 jobExecuteStatusEnum = JobExecuteStatusEnum.RETRY; break; // 删除执行的任务 case REMOVE: QuartzJobContext.removeJob(MicroJobScheduleResource.getScheduler(), jobQueueBean.getJobQueueId(), jobQueueBean.getJobKey()); break; default: // 更新状态为重试 jobExecuteStatusEnum = JobExecuteStatusEnum.RETRY; break; } // 放入重试队列 if (JobExecuteStatusEnum.RETRY.equals(jobExecuteStatusEnum)) { // 任务回收 jobRecovery(jobQueueBean); } // 更新状态 MicroJobScheduleResource.getJobStore().updateJobState(jobQueueBean.getExecuteLogId(), jobExecuteStatusEnum.toString()); // 更新任务消费的消费者地址 MicroJobScheduleResource.getJobStore().updateJobExecuteConsumer(jobQueueBean.getExecuteLogId(), loadBalanceConsumerAddress); } catch (Exception e) { logger.error("Failure of subsequent logical processing for task execution", e); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy