- 3、【新增】新增任务辅助工具 "XxlJobHelper",提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等;
- 3.1、"ShardingUtil" 组件废弃:改用 "XxlJobHelper.getShardIndex()/getShardTotal();" 获取分片参数; - 3.2、"XxlJobLogger" 组件废弃:改用 "XxlJobHelper.log" 进行日志输出; - 4、【优化】任务核心类 "IJobHandler" 的 "execute" 方法取消出入参设计。改为通过 "XxlJobHelper.getJobParam" 获取任务参数并替代方法入参,通过 "XxlJobHelper.handleSuccess/handleFail" 设置任务结果并替代方法出参;
This commit is contained in:
parent
6339f528c5
commit
5dfc6a1092
|
@ -397,9 +397,8 @@ Source code is organized by maven,unzip it and structure is as follows:
|
||||||
xxl-job-admin:schedule admin center
|
xxl-job-admin:schedule admin center
|
||||||
xxl-job-core:public common dependent library
|
xxl-job-core:public common dependent library
|
||||||
xxl-job-executor:executor Sample(Select appropriate version of executor,Can be used directly,You can also refer to it and transform existing projects into executors)
|
xxl-job-executor:executor Sample(Select appropriate version of executor,Can be used directly,You can also refer to it and transform existing projects into executors)
|
||||||
:xxl-job-executor-sample-spring:Spring version,executors managed by Spring,general and recommend;
|
:xxl-job-executor-sample-spring:Spring version,executors managed by Spring,general and recommend;
|
||||||
:xxl-job-executor-sample-springboot:Springboot version,executors managed by Springboot;
|
:xxl-job-executor-sample-springboot:Springboot version,executors managed by Springboot;
|
||||||
:xxl-job-executor-sample-jfinal:JFinal version,executors managed by JFinal;
|
|
||||||
|
|
||||||
### 2.3 Configure and delploy "Schedule Center"
|
### 2.3 Configure and delploy "Schedule Center"
|
||||||
|
|
||||||
|
|
|
@ -559,7 +559,6 @@ XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅
|
||||||
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
|
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
|
||||||
:xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用;
|
:xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用;
|
||||||
:xxl-job-executor-sample-frameless:无框架版本;
|
:xxl-job-executor-sample-frameless:无框架版本;
|
||||||
:xxl-job-executor-sample-jfinal:JFinal版本,通过JFinal管理执行器;
|
|
||||||
|
|
||||||
|
|
||||||
### 2.3 配置部署“调度中心”
|
### 2.3 配置部署“调度中心”
|
||||||
|
@ -714,7 +713,6 @@ public XxlJobSpringExecutor xxlJobExecutor() {
|
||||||
|
|
||||||
xxl-job-executor-sample-springboot:项目编译打包成springboot类型的可执行JAR包,命令启动即可;
|
xxl-job-executor-sample-springboot:项目编译打包成springboot类型的可执行JAR包,命令启动即可;
|
||||||
xxl-job-executor-sample-spring:项目编译打包成WAR包,并部署到tomcat中。
|
xxl-job-executor-sample-spring:项目编译打包成WAR包,并部署到tomcat中。
|
||||||
xxl-job-executor-sample-jfinal:同上
|
|
||||||
|
|
||||||
|
|
||||||
至此“执行器”项目已经部署结束。
|
至此“执行器”项目已经部署结束。
|
||||||
|
@ -1239,7 +1237,7 @@ xxl-job-admin#com.xxl.job.admin.controller.JobApiController.callback
|
||||||
“执行器”接收到“调度中心”的调度请求时,如果任务类型为“Bean模式”,将会匹配Spring容器中的“Bean模式任务”,然后调用其execute方法,执行任务逻辑。如果任务类型为“GLUE模式”,将会加载GLue代码,实例化Java对象,注入依赖的Spring服务(注意:Glue代码中注入的Spring服务,必须存在与该“执行器”项目的Spring容器中),然后调用execute方法,执行任务逻辑。
|
“执行器”接收到“调度中心”的调度请求时,如果任务类型为“Bean模式”,将会匹配Spring容器中的“Bean模式任务”,然后调用其execute方法,执行任务逻辑。如果任务类型为“GLUE模式”,将会加载GLue代码,实例化Java对象,注入依赖的Spring服务(注意:Glue代码中注入的Spring服务,必须存在与该“执行器”项目的Spring容器中),然后调用execute方法,执行任务逻辑。
|
||||||
|
|
||||||
#### 5.5.5 任务日志
|
#### 5.5.5 任务日志
|
||||||
XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 "XxlJobLogger.log" 打印执行日志,“调度中心”查看执行日志时将会加载对应的日志文件。
|
XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 "XxlJobHelper.log" 打印执行日志,“调度中心”查看执行日志时将会加载对应的日志文件。
|
||||||
|
|
||||||
(历史版本通过重写LOG4J的Appender实现,存在依赖限制,该方式在新版本已经被抛弃)
|
(历史版本通过重写LOG4J的Appender实现,存在依赖限制,该方式在新版本已经被抛弃)
|
||||||
|
|
||||||
|
@ -2062,37 +2060,38 @@ data: post-data
|
||||||
注意:XxlJobSpringExecutor组件个别字段调整:“appName” 调整为 “appname” ,升级时该组件时需要注意;
|
注意:XxlJobSpringExecutor组件个别字段调整:“appName” 调整为 “appname” ,升级时该组件时需要注意;
|
||||||
|
|
||||||
### 7.31 版本 v2.3.0 Release Notes[迭代中]
|
### 7.31 版本 v2.3.0 Release Notes[迭代中]
|
||||||
- 1、新增调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
|
- 1、【新增】调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
|
||||||
- 2、新增触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 "固定间隔触发、固定延时触发(规划)" 两种新触发方式;
|
- 2、【新增】触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 "固定间隔触发、(固定延时触发,实验中)" 新触发方式;
|
||||||
- 3、Cron编辑器增强:Cron编辑器修改cron时可实时查看最近运行时间;
|
- 3、【新增】新增任务辅助工具 "XxlJobHelper",提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等;
|
||||||
- 4、Cron编辑器问题修复:修复小概率情况下cron单个字段修改时导致其他字段被重置问题;
|
- 3.1、"ShardingUtil" 组件废弃:改用 "XxlJobHelper.getShardIndex()/getShardTotal();" 获取分片参数;
|
||||||
- 5、新增任务属性 "XxlJobContext" ,统一维护任务上下文信息,包括任务ID、分片参数等,方便运行时存取任务相关信息;
|
- 3.2、"XxlJobLogger" 组件废弃:改用 "XxlJobHelper.log" 进行日志输出;
|
||||||
- 6.1、废弃 "ShardingUtil" 组件:改用 "XxlJobContext.getXxlJobContext().getShardIndex()/getShardTotal();" 获取分片参数;
|
- 4、【优化】任务核心类 "IJobHandler" 的 "execute" 方法取消出入参设计。改为通过 "XxlJobHelper.getJobParam" 获取任务参数并替代方法入参,通过 "XxlJobHelper.handleSuccess/handleFail" 设置任务结果并替代方法出参;
|
||||||
- 6.2、日志组件逻辑调整:日志组件改为通过 XxlJobContext 获取任务上下文并匹配写入对应日志文件;
|
- 4、【优化】Cron编辑器增强:Cron编辑器修改cron时可实时查看最近运行时间;
|
||||||
- 6、执行器注册组件优化:注册逻辑调整为异步方式,提高注册性能;
|
- 5、【优化】执行器示例项目规范整理;
|
||||||
- 7、执行器鉴权校验:执行器启动时主动校验accessToken,为空则主动Warn告警;(已规划安全强化:AccessToken动态生成、动态启停等)
|
- 6、【优化】任务调度生命周期重构:调度(schedule)、触发(trigger)、执行(handle)、回调(callback)、结束(complete);
|
||||||
- 8、邮箱告警配置优化:将"spring.mail.from"与"spring.mail.username"属性拆分开,更加灵活的支持一些无密码邮箱服务;
|
- 7、【优化】[规划中]任务日志重构:一次调度只记录一条主任务,维护起止时间和状态。
|
||||||
- 9、多个项目依赖升级至较新稳定版本,如netty、groovy、spring、springboot、mybatis等;
|
|
||||||
- 10、UI组件常规升级,提升组件稳定性;
|
|
||||||
- 11、调度中心页面交互优化:用户管理模块密码列取消;多处表达autocomplete取消;执行器管理模块XSS拦截校验等;
|
|
||||||
- 12、通用HTTP任务Handler(httpJobHandler)优化:修复 "setDoOutput(true)" 导致任务请求GetMethod失效问题;
|
|
||||||
- 13、执行器Commandhandler示例任务优化,修复极端情况下脚本进程挂起问题;
|
|
||||||
- 14、调度通讯组件优化,修复RestFul方式调用 DotNet 版本执行器时心跳检测失败问题;
|
|
||||||
- 15、调度中心远程执行日志查询乱码问题修复;
|
|
||||||
- 16、调度中心组件加载顺序优化,修复极端情况下调度组件初始慢导致的调度失败问题;
|
|
||||||
- 17、执行器注册线程优化,修复极端情况下初始化失败时导致NPE问题;
|
|
||||||
- 18、调度线程连接池优化,修复连接有效性校验超时问题;
|
|
||||||
- 19、执行器注册表字段优化,解决执行器注册节点过多导致注册信息存储和更新失败的问题;
|
|
||||||
- 20、轮训路由策略优化,修复小概率下并发问题;
|
|
||||||
- 21、页面redirect跳转后https变为http问题修复;
|
|
||||||
- 22、执行器日志清理优化,修复小概率下日志文件为空导致清理异常问题;
|
|
||||||
- 23、执行器示例项目规范整理;
|
|
||||||
- 24、任务调度生命周期重构:调度(schedule)、触发(trigger)、执行(handle)、回调(callback)、结束(complete);
|
|
||||||
- 25、[规划中]任务日志重构:一次调度只记录一条主任务,维护起止时间和状态。
|
|
||||||
- 普通任务:只记录一条主任务;
|
- 普通任务:只记录一条主任务;
|
||||||
- 广播任务:记录一条主任务,每个分片任务记录一条次任务,关联在主任务上;
|
- 广播任务:记录一条主任务,每个分片任务记录一条次任务,关联在主任务上;
|
||||||
- 重试任务:失败时,新增主任务。所有调度记录,包括入口调度和重试调度,均挂载主任务上。
|
- 重试任务:失败时,新增主任务。所有调度记录,包括入口调度和重试调度,均挂载主任务上。
|
||||||
- 26、[规划中]分片任务:全部完成后才会出发后置节点;
|
- 8、【优化】[规划中]分片任务:全部完成后才会出发后置节点;
|
||||||
|
- 9、【优化】执行器注册组件优化:注册逻辑调整为异步方式,提高注册性能;
|
||||||
|
- 10、【优化】执行器鉴权校验:执行器启动时主动校验accessToken,为空则主动Warn告警;(已规划安全强化:AccessToken动态生成、动态启停等)
|
||||||
|
- 11、【优化】邮箱告警配置优化:将"spring.mail.from"与"spring.mail.username"属性拆分开,更加灵活的支持一些无密码邮箱服务;
|
||||||
|
- 12、【优化】多个项目依赖升级至较新稳定版本,如netty、groovy、spring、springboot、mybatis等;
|
||||||
|
- 13、【优化】UI组件常规升级,提升组件稳定性;
|
||||||
|
- 14、【优化】调度中心页面交互优化:用户管理模块密码列取消;多处表达autocomplete取消;执行器管理模块XSS拦截校验等;
|
||||||
|
- 15、【修复】Cron编辑器问题修复:修复小概率情况下cron单个字段修改时导致其他字段被重置问题;
|
||||||
|
- 16、【修复】通用HTTP任务Handler(httpJobHandler)优化:修复 "setDoOutput(true)" 导致任务请求GetMethod失效问题;
|
||||||
|
- 17、【修复】执行器Commandhandler示例任务优化,修复极端情况下脚本进程挂起问题;
|
||||||
|
- 18、【修复】调度通讯组件优化,修复RestFul方式调用 DotNet 版本执行器时心跳检测失败问题;
|
||||||
|
- 19、【修复】调度中心远程执行日志查询乱码问题修复;
|
||||||
|
- 20、【修复】调度中心组件加载顺序优化,修复极端情况下调度组件初始慢导致的调度失败问题;
|
||||||
|
- 21、【修复】执行器注册线程优化,修复极端情况下初始化失败时导致NPE问题;
|
||||||
|
- 22、【修复】调度线程连接池优化,修复连接有效性校验超时问题;
|
||||||
|
- 23、【修复】执行器注册表字段优化,解决执行器注册节点过多导致注册信息存储和更新失败的问题;
|
||||||
|
- 24、【修复】轮训路由策略优化,修复小概率下并发问题;
|
||||||
|
- 25、【修复】页面redirect跳转后https变为http问题修复;
|
||||||
|
- 26、【修复】执行器日志清理优化,修复小概率下日志文件为空导致清理异常问题;
|
||||||
|
|
||||||
|
|
||||||
### 7.32 版本 v2.4.0 Release Notes[规划中]
|
### 7.32 版本 v2.4.0 Release Notes[规划中]
|
||||||
|
|
|
@ -7,7 +7,7 @@ import com.xxl.job.admin.core.thread.JobTriggerPoolHelper;
|
||||||
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
import com.xxl.job.admin.core.trigger.TriggerTypeEnum;
|
||||||
import com.xxl.job.admin.core.util.I18nUtil;
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.context.XxlJobContext;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ public class XxlJobCompleter {
|
||||||
|
|
||||||
// 1、handle success, to trigger child job
|
// 1、handle success, to trigger child job
|
||||||
String triggerChildMsg = null;
|
String triggerChildMsg = null;
|
||||||
if (IJobHandler.SUCCESS.getCode() == xxlJobLog.getHandleCode()) {
|
if (XxlJobContext.HANDLE_COCE_SUCCESS == xxlJobLog.getHandleCode()) {
|
||||||
XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
|
XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
|
||||||
if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
|
if (xxlJobInfo!=null && xxlJobInfo.getChildJobId()!=null && xxlJobInfo.getChildJobId().trim().length()>0) {
|
||||||
triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< </span><br>";
|
triggerChildMsg = "<br><br><span style=\"color:#00c0ef;\" > >>>>>>>>>>>"+ I18nUtil.getString("jobconf_trigger_child_run") +"<<<<<<<<<<< </span><br>";
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
package com.xxl.job.admin.core.thread;
|
package com.xxl.job.admin.core.thread;
|
||||||
|
|
||||||
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
|
||||||
import com.xxl.job.admin.core.complete.XxlJobCompleter;
|
import com.xxl.job.admin.core.complete.XxlJobCompleter;
|
||||||
|
import com.xxl.job.admin.core.conf.XxlJobAdminConfig;
|
||||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||||
import com.xxl.job.admin.core.util.I18nUtil;
|
import com.xxl.job.admin.core.util.I18nUtil;
|
||||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.util.DateUtil;
|
import com.xxl.job.core.util.DateUtil;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
@ -144,7 +143,7 @@ public class JobCompleteHelper {
|
||||||
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
|
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
|
||||||
ReturnT<String> callbackResult = callback(handleCallbackParam);
|
ReturnT<String> callbackResult = callback(handleCallbackParam);
|
||||||
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
|
logger.debug(">>>>>>>>> JobApiController.callback {}, handleCallbackParam={}, callbackResult={}",
|
||||||
(callbackResult.getCode()== IJobHandler.SUCCESS.getCode()?"success":"fail"), handleCallbackParam, callbackResult);
|
(callbackResult.getCode()== ReturnT.SUCCESS_CODE?"success":"fail"), handleCallbackParam, callbackResult);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -167,13 +166,13 @@ public class JobCompleteHelper {
|
||||||
if (log.getHandleMsg()!=null) {
|
if (log.getHandleMsg()!=null) {
|
||||||
handleMsg.append(log.getHandleMsg()).append("<br>");
|
handleMsg.append(log.getHandleMsg()).append("<br>");
|
||||||
}
|
}
|
||||||
if (handleCallbackParam.getExecuteResult().getMsg() != null) {
|
if (handleCallbackParam.getHandleMsg() != null) {
|
||||||
handleMsg.append(handleCallbackParam.getExecuteResult().getMsg());
|
handleMsg.append(handleCallbackParam.getHandleMsg());
|
||||||
}
|
}
|
||||||
|
|
||||||
// success, save log
|
// success, save log
|
||||||
log.setHandleTime(new Date());
|
log.setHandleTime(new Date());
|
||||||
log.setHandleCode(handleCallbackParam.getExecuteResult().getCode());
|
log.setHandleCode(handleCallbackParam.getHandleCode());
|
||||||
log.setHandleMsg(handleMsg.toString());
|
log.setHandleMsg(handleMsg.toString());
|
||||||
XxlJobCompleter.updateHandleInfoAndFinish(log);
|
XxlJobCompleter.updateHandleInfoAndFinish(log);
|
||||||
|
|
||||||
|
|
|
@ -374,6 +374,12 @@ $(function() {
|
||||||
$("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
|
$("#addModal .form input[name='schedule_conf_CRON']").show().siblings().remove();
|
||||||
$("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
|
$("#addModal .form input[name='schedule_conf_CRON']").cronGen({});
|
||||||
|
|
||||||
|
// 》init scheduleType
|
||||||
|
$("#updateModal .form select[name=scheduleType]").change();
|
||||||
|
|
||||||
|
// 》init glueType
|
||||||
|
$("#updateModal .form select[name=glueType]").change();
|
||||||
|
|
||||||
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
$('#addModal').modal({backdrop: false, keyboard: false}).modal('show');
|
||||||
});
|
});
|
||||||
var addModalValidate = $("#addModal .form").validate({
|
var addModalValidate = $("#addModal .form").validate({
|
||||||
|
|
|
@ -245,16 +245,14 @@
|
||||||
<textarea class="glueSource_java" style="display:none;" >
|
<textarea class="glueSource_java" style="display:none;" >
|
||||||
package com.xxl.job.service.handler;
|
package com.xxl.job.service.handler;
|
||||||
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.handler.IJobHandler;
|
||||||
|
|
||||||
public class DemoGlueJobHandler extends IJobHandler {
|
public class DemoGlueJobHandler extends IJobHandler {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
public void execute() throws Exception {
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.xxl.job.core.biz.client.AdminBizClient;
|
||||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||||
import com.xxl.job.core.biz.model.RegistryParam;
|
import com.xxl.job.core.biz.model.RegistryParam;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
|
import com.xxl.job.core.context.XxlJobContext;
|
||||||
import com.xxl.job.core.enums.RegistryConfig;
|
import com.xxl.job.core.enums.RegistryConfig;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
@ -30,7 +31,7 @@ public class AdminBizTest {
|
||||||
|
|
||||||
HandleCallbackParam param = new HandleCallbackParam();
|
HandleCallbackParam param = new HandleCallbackParam();
|
||||||
param.setLogId(1);
|
param.setLogId(1);
|
||||||
param.setExecuteResult(ReturnT.SUCCESS);
|
param.setHandleCode(XxlJobContext.HANDLE_COCE_SUCCESS);
|
||||||
|
|
||||||
List<HandleCallbackParam> callbackParamList = Arrays.asList(param);
|
List<HandleCallbackParam> callbackParamList = Arrays.asList(param);
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,15 @@ public class HandleCallbackParam implements Serializable {
|
||||||
private long logId;
|
private long logId;
|
||||||
private long logDateTim;
|
private long logDateTim;
|
||||||
|
|
||||||
private ReturnT<String> executeResult;
|
private int handleCode;
|
||||||
|
private String handleMsg;
|
||||||
|
|
||||||
public HandleCallbackParam(){}
|
public HandleCallbackParam(){}
|
||||||
public HandleCallbackParam(long logId, long logDateTim, ReturnT<String> executeResult) {
|
public HandleCallbackParam(long logId, long logDateTim, int handleCode, String handleMsg) {
|
||||||
this.logId = logId;
|
this.logId = logId;
|
||||||
this.logDateTim = logDateTim;
|
this.logDateTim = logDateTim;
|
||||||
this.executeResult = executeResult;
|
this.handleCode = handleCode;
|
||||||
|
this.handleMsg = handleMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getLogId() {
|
public long getLogId() {
|
||||||
|
@ -36,12 +38,20 @@ public class HandleCallbackParam implements Serializable {
|
||||||
this.logDateTim = logDateTim;
|
this.logDateTim = logDateTim;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReturnT<String> getExecuteResult() {
|
public int getHandleCode() {
|
||||||
return executeResult;
|
return handleCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExecuteResult(ReturnT<String> executeResult) {
|
public void setHandleCode(int handleCode) {
|
||||||
this.executeResult = executeResult;
|
this.handleCode = handleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHandleMsg() {
|
||||||
|
return handleMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandleMsg(String handleMsg) {
|
||||||
|
this.handleMsg = handleMsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -49,7 +59,8 @@ public class HandleCallbackParam implements Serializable {
|
||||||
return "HandleCallbackParam{" +
|
return "HandleCallbackParam{" +
|
||||||
"logId=" + logId +
|
"logId=" + logId +
|
||||||
", logDateTim=" + logDateTim +
|
", logDateTim=" + logDateTim +
|
||||||
", executeResult=" + executeResult +
|
", handleCode=" + handleCode +
|
||||||
|
", handleMsg='" + handleMsg + '\'' +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,16 +8,31 @@ package com.xxl.job.core.context;
|
||||||
*/
|
*/
|
||||||
public class XxlJobContext {
|
public class XxlJobContext {
|
||||||
|
|
||||||
|
public static final int HANDLE_COCE_SUCCESS = 200;
|
||||||
|
public static final int HANDLE_COCE_FAIL = 500;
|
||||||
|
public static final int HANDLE_COCE_TIMEOUT = 502;
|
||||||
|
|
||||||
|
// ---------------------- base info ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* job id
|
* job id
|
||||||
*/
|
*/
|
||||||
private final long jobId;
|
private final long jobId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* job param
|
||||||
|
*/
|
||||||
|
private final String jobParam;
|
||||||
|
|
||||||
|
// ---------------------- for log ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* job log filename
|
* job log filename
|
||||||
*/
|
*/
|
||||||
private final String jobLogFileName;
|
private final String jobLogFileName;
|
||||||
|
|
||||||
|
// ---------------------- for shard ----------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* shard index
|
* shard index
|
||||||
*/
|
*/
|
||||||
|
@ -28,18 +43,42 @@ public class XxlJobContext {
|
||||||
*/
|
*/
|
||||||
private final int shardTotal;
|
private final int shardTotal;
|
||||||
|
|
||||||
|
// ---------------------- for handle ----------------------
|
||||||
|
|
||||||
public XxlJobContext(long jobId, String jobLogFileName, int shardIndex, int shardTotal) {
|
/**
|
||||||
|
* handleCode:The result status of job execution
|
||||||
|
*
|
||||||
|
* 200 : success
|
||||||
|
* 500 : fail
|
||||||
|
* 502 : timeout
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private int handleCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handleMsg:The simple log msg of job execution
|
||||||
|
*/
|
||||||
|
private String handleMsg;
|
||||||
|
|
||||||
|
|
||||||
|
public XxlJobContext(long jobId, String jobParam, String jobLogFileName, int shardIndex, int shardTotal) {
|
||||||
this.jobId = jobId;
|
this.jobId = jobId;
|
||||||
|
this.jobParam = jobParam;
|
||||||
this.jobLogFileName = jobLogFileName;
|
this.jobLogFileName = jobLogFileName;
|
||||||
this.shardIndex = shardIndex;
|
this.shardIndex = shardIndex;
|
||||||
this.shardTotal = shardTotal;
|
this.shardTotal = shardTotal;
|
||||||
|
|
||||||
|
this.handleCode = HANDLE_COCE_SUCCESS; // default success
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getJobId() {
|
public long getJobId() {
|
||||||
return jobId;
|
return jobId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getJobParam() {
|
||||||
|
return jobParam;
|
||||||
|
}
|
||||||
|
|
||||||
public String getJobLogFileName() {
|
public String getJobLogFileName() {
|
||||||
return jobLogFileName;
|
return jobLogFileName;
|
||||||
}
|
}
|
||||||
|
@ -52,6 +91,21 @@ public class XxlJobContext {
|
||||||
return shardTotal;
|
return shardTotal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setHandleCode(int handleCode) {
|
||||||
|
this.handleCode = handleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getHandleCode() {
|
||||||
|
return handleCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHandleMsg(String handleMsg) {
|
||||||
|
this.handleMsg = handleMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getHandleMsg() {
|
||||||
|
return handleMsg;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------- tool ----------------------
|
// ---------------------- tool ----------------------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
package com.xxl.job.core.context;
|
||||||
|
|
||||||
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
|
import com.xxl.job.core.util.DateUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.slf4j.helpers.FormattingTuple;
|
||||||
|
import org.slf4j.helpers.MessageFormatter;
|
||||||
|
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* helper for xxl-job
|
||||||
|
*
|
||||||
|
* @author xuxueli 2020-11-05
|
||||||
|
*/
|
||||||
|
public class XxlJobHelper {
|
||||||
|
|
||||||
|
// ---------------------- base info ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current JobId
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static long getJobId() {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xxlJobContext.getJobId();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current JobParam
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getJobParam() {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xxlJobContext.getJobParam();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- for log ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current JobLogFileName
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getJobLogFileName() {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xxlJobContext.getJobLogFileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- for shard ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current ShardIndex
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getShardIndex() {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xxlJobContext.getShardIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* current ShardTotal
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int getShardTotal() {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return xxlJobContext.getShardTotal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- tool for log ----------------------
|
||||||
|
|
||||||
|
private static Logger logger = LoggerFactory.getLogger("xxl-job logger");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append log with pattern
|
||||||
|
*
|
||||||
|
* @param appendLogPattern like "aaa {} bbb {} ccc"
|
||||||
|
* @param appendLogArguments like "111, true"
|
||||||
|
*/
|
||||||
|
public static boolean log(String appendLogPattern, Object ... appendLogArguments) {
|
||||||
|
|
||||||
|
FormattingTuple ft = MessageFormatter.arrayFormat(appendLogPattern, appendLogArguments);
|
||||||
|
String appendLog = ft.getMessage();
|
||||||
|
|
||||||
|
/*appendLog = appendLogPattern;
|
||||||
|
if (appendLogArguments!=null && appendLogArguments.length>0) {
|
||||||
|
appendLog = MessageFormat.format(appendLogPattern, appendLogArguments);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
StackTraceElement callInfo = new Throwable().getStackTrace()[1];
|
||||||
|
return logDetail(callInfo, appendLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append exception stack
|
||||||
|
*
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
public static boolean log(Throwable e) {
|
||||||
|
|
||||||
|
StringWriter stringWriter = new StringWriter();
|
||||||
|
e.printStackTrace(new PrintWriter(stringWriter));
|
||||||
|
String appendLog = stringWriter.toString();
|
||||||
|
|
||||||
|
StackTraceElement callInfo = new Throwable().getStackTrace()[1];
|
||||||
|
return logDetail(callInfo, appendLog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* append log
|
||||||
|
*
|
||||||
|
* @param callInfo
|
||||||
|
* @param appendLog
|
||||||
|
*/
|
||||||
|
private static boolean logDetail(StackTraceElement callInfo, String appendLog) {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*// "yyyy-MM-dd HH:mm:ss [ClassName]-[MethodName]-[LineNumber]-[ThreadName] log";
|
||||||
|
StackTraceElement[] stackTraceElements = new Throwable().getStackTrace();
|
||||||
|
StackTraceElement callInfo = stackTraceElements[1];*/
|
||||||
|
|
||||||
|
StringBuffer stringBuffer = new StringBuffer();
|
||||||
|
stringBuffer.append(DateUtil.formatDateTime(new Date())).append(" ")
|
||||||
|
.append("["+ callInfo.getClassName() + "#" + callInfo.getMethodName() +"]").append("-")
|
||||||
|
.append("["+ callInfo.getLineNumber() +"]").append("-")
|
||||||
|
.append("["+ Thread.currentThread().getName() +"]").append(" ")
|
||||||
|
.append(appendLog!=null?appendLog:"");
|
||||||
|
String formatAppendLog = stringBuffer.toString();
|
||||||
|
|
||||||
|
// appendlog
|
||||||
|
String logFileName = xxlJobContext.getJobLogFileName();
|
||||||
|
|
||||||
|
if (logFileName!=null && logFileName.trim().length()>0) {
|
||||||
|
XxlJobFileAppender.appendLog(logFileName, formatAppendLog);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
logger.info(">>>>>>>>>>> {}", formatAppendLog);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------- tool for handleResult ----------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle success
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleSuccess(){
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_SUCCESS, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle success with log msg
|
||||||
|
*
|
||||||
|
* @param handleMsg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleSuccess(String handleMsg) {
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_SUCCESS, handleMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle fail
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleFail(){
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_FAIL, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle fail with log msg
|
||||||
|
*
|
||||||
|
* @param handleMsg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleFail(String handleMsg) {
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_FAIL, handleMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle timeout
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleTimeout(){
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_TIMEOUT, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* handle timeout with log msg
|
||||||
|
*
|
||||||
|
* @param handleMsg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleTimeout(String handleMsg){
|
||||||
|
return handleResult(XxlJobContext.HANDLE_COCE_TIMEOUT, handleMsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param handleCode
|
||||||
|
*
|
||||||
|
* 200 : success
|
||||||
|
* 500 : fail
|
||||||
|
* 502 : timeout
|
||||||
|
*
|
||||||
|
* @param handleMsg
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean handleResult(int handleCode, String handleMsg) {
|
||||||
|
XxlJobContext xxlJobContext = XxlJobContext.getXxlJobContext();
|
||||||
|
if (xxlJobContext == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
xxlJobContext.setHandleCode(handleCode);
|
||||||
|
if (handleMsg != null) {
|
||||||
|
xxlJobContext.setHandleMsg(handleMsg);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -169,13 +169,13 @@ public class XxlJobExecutor {
|
||||||
|
|
||||||
// ---------------------- job handler repository ----------------------
|
// ---------------------- job handler repository ----------------------
|
||||||
private static ConcurrentMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
|
private static ConcurrentMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();
|
||||||
|
public static IJobHandler loadJobHandler(String name){
|
||||||
|
return jobHandlerRepository.get(name);
|
||||||
|
}
|
||||||
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
|
public static IJobHandler registJobHandler(String name, IJobHandler jobHandler){
|
||||||
logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
|
logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
|
||||||
return jobHandlerRepository.put(name, jobHandler);
|
return jobHandlerRepository.put(name, jobHandler);
|
||||||
}
|
}
|
||||||
public static IJobHandler loadJobHandler(String name){
|
|
||||||
return jobHandlerRepository.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ---------------------- job thread repository ----------------------
|
// ---------------------- job thread repository ----------------------
|
||||||
|
|
|
@ -0,0 +1,122 @@
|
||||||
|
package com.xxl.job.core.executor.impl;
|
||||||
|
|
||||||
|
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||||
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
import com.xxl.job.core.handler.impl.MethodJobHandler;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* xxl-job executor (for frameless)
|
||||||
|
*
|
||||||
|
* @author xuxueli 2020-11-05
|
||||||
|
*/
|
||||||
|
public class XxlJobSimpleExecutor extends XxlJobExecutor {
|
||||||
|
private static final Logger logger = LoggerFactory.getLogger(XxlJobSimpleExecutor.class);
|
||||||
|
|
||||||
|
|
||||||
|
private List<Object> xxlJobBeanList = new ArrayList<>();
|
||||||
|
public List<Object> getXxlJobBeanList() {
|
||||||
|
return xxlJobBeanList;
|
||||||
|
}
|
||||||
|
public void setXxlJobBeanList(List<Object> xxlJobBeanList) {
|
||||||
|
this.xxlJobBeanList = xxlJobBeanList;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
|
||||||
|
// init JobHandler Repository (for method)
|
||||||
|
initJobHandlerMethodRepository(xxlJobBeanList);
|
||||||
|
|
||||||
|
// super start
|
||||||
|
try {
|
||||||
|
super.start();
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroy() {
|
||||||
|
super.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initJobHandlerMethodRepository(List<Object> xxlJobBeanList) {
|
||||||
|
if (xxlJobBeanList==null || xxlJobBeanList.size()==0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// init job handler from method
|
||||||
|
for (Object bean: xxlJobBeanList) {
|
||||||
|
// method
|
||||||
|
Method[] methods = bean.getClass().getDeclaredMethods();
|
||||||
|
if (methods==null || methods.length==0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Method executeMethod : methods) {
|
||||||
|
|
||||||
|
// anno
|
||||||
|
XxlJob xxlJob = executeMethod.getAnnotation(XxlJob.class);
|
||||||
|
if (xxlJob == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String name = xxlJob.value();
|
||||||
|
if (name.trim().length() == 0) {
|
||||||
|
throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
|
}
|
||||||
|
if (loadJobHandler(name) != null) {
|
||||||
|
throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// execute method
|
||||||
|
/*if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
|
||||||
|
throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
||||||
|
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
||||||
|
}
|
||||||
|
if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
|
||||||
|
throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
||||||
|
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
executeMethod.setAccessible(true);
|
||||||
|
|
||||||
|
// init and destory
|
||||||
|
Method initMethod = null;
|
||||||
|
Method destroyMethod = null;
|
||||||
|
|
||||||
|
if (xxlJob.init().trim().length() > 0) {
|
||||||
|
try {
|
||||||
|
initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
|
||||||
|
initMethod.setAccessible(true);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (xxlJob.destroy().trim().length() > 0) {
|
||||||
|
try {
|
||||||
|
destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
|
||||||
|
destroyMethod.setAccessible(true);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// registry jobhandler
|
||||||
|
registJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod));
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
package com.xxl.job.core.executor.impl;
|
package com.xxl.job.core.executor.impl;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||||
import com.xxl.job.core.glue.GlueFactory;
|
import com.xxl.job.core.glue.GlueFactory;
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
@ -104,7 +103,7 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {
|
for (Map.Entry<Method, XxlJob> methodXxlJobEntry : annotatedMethods.entrySet()) {
|
||||||
Method method = methodXxlJobEntry.getKey();
|
Method executeMethod = methodXxlJobEntry.getKey();
|
||||||
XxlJob xxlJob = methodXxlJobEntry.getValue();
|
XxlJob xxlJob = methodXxlJobEntry.getValue();
|
||||||
if (xxlJob == null) {
|
if (xxlJob == null) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -112,22 +111,23 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
||||||
|
|
||||||
String name = xxlJob.value();
|
String name = xxlJob.value();
|
||||||
if (name.trim().length() == 0) {
|
if (name.trim().length() == 0) {
|
||||||
throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
|
throw new RuntimeException("xxl-job method-jobhandler name invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
}
|
}
|
||||||
if (loadJobHandler(name) != null) {
|
if (loadJobHandler(name) != null) {
|
||||||
throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
|
throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
|
||||||
}
|
}
|
||||||
|
|
||||||
// execute method
|
// execute method
|
||||||
if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
|
/*if (!(method.getParameterTypes().length == 1 && method.getParameterTypes()[0].isAssignableFrom(String.class))) {
|
||||||
throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
throw new RuntimeException("xxl-job method-jobhandler param-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
||||||
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
||||||
}
|
}
|
||||||
if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
|
if (!method.getReturnType().isAssignableFrom(ReturnT.class)) {
|
||||||
throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
throw new RuntimeException("xxl-job method-jobhandler return-classtype invalid, for[" + bean.getClass() + "#" + method.getName() + "] , " +
|
||||||
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
"The correct method format like \" public ReturnT<String> execute(String param) \" .");
|
||||||
}
|
}*/
|
||||||
method.setAccessible(true);
|
|
||||||
|
executeMethod.setAccessible(true);
|
||||||
|
|
||||||
// init and destory
|
// init and destory
|
||||||
Method initMethod = null;
|
Method initMethod = null;
|
||||||
|
@ -138,7 +138,7 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
||||||
initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
|
initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
|
||||||
initMethod.setAccessible(true);
|
initMethod.setAccessible(true);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
|
throw new RuntimeException("xxl-job method-jobhandler initMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (xxlJob.destroy().trim().length() > 0) {
|
if (xxlJob.destroy().trim().length() > 0) {
|
||||||
|
@ -146,12 +146,12 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
||||||
destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
|
destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
|
||||||
destroyMethod.setAccessible(true);
|
destroyMethod.setAccessible(true);
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + method.getName() + "] .");
|
throw new RuntimeException("xxl-job method-jobhandler destroyMethod invalid, for[" + bean.getClass() + "#" + executeMethod.getName() + "] .");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// registry jobhandler
|
// registry jobhandler
|
||||||
registJobHandler(name, new MethodJobHandler(bean, method, initMethod, destroyMethod));
|
registJobHandler(name, new MethodJobHandler(bean, executeMethod, initMethod, destroyMethod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
package com.xxl.job.core.handler;
|
package com.xxl.job.core.handler;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* job handler
|
* job handler
|
||||||
*
|
*
|
||||||
|
@ -12,28 +8,21 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
public abstract class IJobHandler {
|
public abstract class IJobHandler {
|
||||||
|
|
||||||
|
|
||||||
/** success */
|
|
||||||
public static final ReturnT<String> SUCCESS = new ReturnT<String>(200, null);
|
|
||||||
/** fail */
|
|
||||||
public static final ReturnT<String> FAIL = new ReturnT<String>(500, null);
|
|
||||||
/** fail timeout */
|
|
||||||
public static final ReturnT<String> FAIL_TIMEOUT = new ReturnT<String>(502, null);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* execute handler, invoked when executor receives a scheduling request
|
* execute handler, invoked when executor receives a scheduling request
|
||||||
*
|
*
|
||||||
* @param param
|
|
||||||
* @return
|
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public abstract ReturnT<String> execute(String param) throws Exception;
|
public abstract void execute() throws Exception;
|
||||||
|
|
||||||
|
|
||||||
|
/*@Deprecated
|
||||||
|
public abstract ReturnT<String> execute(String param) throws Exception;*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init handler, invoked when JobThread init
|
* init handler, invoked when JobThread init
|
||||||
*/
|
*/
|
||||||
public void init() throws InvocationTargetException, IllegalAccessException {
|
public void init() throws Exception {
|
||||||
// do something
|
// do something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +30,7 @@ public abstract class IJobHandler {
|
||||||
/**
|
/**
|
||||||
* destroy handler, invoked when JobThread destroy
|
* destroy handler, invoked when JobThread destroy
|
||||||
*/
|
*/
|
||||||
public void destroy() throws InvocationTargetException, IllegalAccessException {
|
public void destroy() throws Exception {
|
||||||
// do something
|
// do something
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
package com.xxl.job.core.handler.impl;
|
package com.xxl.job.core.handler.impl;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.handler.IJobHandler;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* glue job handler
|
* glue job handler
|
||||||
|
@ -22,9 +21,9 @@ public class GlueJobHandler extends IJobHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
public void execute() throws Exception {
|
||||||
XxlJobLogger.log("----------- glue.version:"+ glueUpdatetime +" -----------");
|
XxlJobHelper.log("----------- glue.version:"+ glueUpdatetime +" -----------");
|
||||||
return jobHandler.execute(param);
|
jobHandler.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
package com.xxl.job.core.handler.impl;
|
package com.xxl.job.core.handler.impl;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.handler.IJobHandler;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,24 +18,24 @@ public class MethodJobHandler extends IJobHandler {
|
||||||
this.target = target;
|
this.target = target;
|
||||||
this.method = method;
|
this.method = method;
|
||||||
|
|
||||||
this.initMethod =initMethod;
|
this.initMethod = initMethod;
|
||||||
this.destroyMethod =destroyMethod;
|
this.destroyMethod = destroyMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
public void execute() throws Exception {
|
||||||
return (ReturnT<String>) method.invoke(target, new Object[]{param});
|
method.invoke(target);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() throws InvocationTargetException, IllegalAccessException {
|
public void init() throws Exception {
|
||||||
if(initMethod != null) {
|
if(initMethod != null) {
|
||||||
initMethod.invoke(target);
|
initMethod.invoke(target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void destroy() throws InvocationTargetException, IllegalAccessException {
|
public void destroy() throws Exception {
|
||||||
if(destroyMethod != null) {
|
if(destroyMethod != null) {
|
||||||
destroyMethod.invoke(target);
|
destroyMethod.invoke(target);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package com.xxl.job.core.handler.impl;
|
package com.xxl.job.core.handler.impl;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
import com.xxl.job.core.context.XxlJobContext;
|
||||||
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.glue.GlueTypeEnum;
|
import com.xxl.job.core.glue.GlueTypeEnum;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.handler.IJobHandler;
|
||||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
import com.xxl.job.core.util.ScriptUtil;
|
import com.xxl.job.core.util.ScriptUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -46,10 +45,11 @@ public class ScriptJobHandler extends IJobHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
public void execute() throws Exception {
|
||||||
|
|
||||||
if (!glueType.isScript()) {
|
if (!glueType.isScript()) {
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "glueType["+ glueType +"] invalid.");
|
XxlJobHelper.handleFail("glueType["+ glueType +"] invalid.");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cmd
|
// cmd
|
||||||
|
@ -72,18 +72,20 @@ public class ScriptJobHandler extends IJobHandler {
|
||||||
|
|
||||||
// script params:0=param、1=分片序号、2=分片总数
|
// script params:0=param、1=分片序号、2=分片总数
|
||||||
String[] scriptParams = new String[3];
|
String[] scriptParams = new String[3];
|
||||||
scriptParams[0] = param;
|
scriptParams[0] = XxlJobHelper.getJobParam();
|
||||||
scriptParams[1] = String.valueOf(XxlJobContext.getXxlJobContext().getShardIndex());
|
scriptParams[1] = String.valueOf(XxlJobContext.getXxlJobContext().getShardIndex());
|
||||||
scriptParams[2] = String.valueOf(XxlJobContext.getXxlJobContext().getShardTotal());
|
scriptParams[2] = String.valueOf(XxlJobContext.getXxlJobContext().getShardTotal());
|
||||||
|
|
||||||
// invoke
|
// invoke
|
||||||
XxlJobLogger.log("----------- script file:"+ scriptFileName +" -----------");
|
XxlJobHelper.log("----------- script file:"+ scriptFileName +" -----------");
|
||||||
int exitValue = ScriptUtil.execToFile(cmd, scriptFileName, logFileName, scriptParams);
|
int exitValue = ScriptUtil.execToFile(cmd, scriptFileName, logFileName, scriptParams);
|
||||||
|
|
||||||
if (exitValue == 0) {
|
if (exitValue == 0) {
|
||||||
return IJobHandler.SUCCESS;
|
XxlJobHelper.handleSuccess();
|
||||||
|
return;
|
||||||
} else {
|
} else {
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "script exit value("+exitValue+") is failed");
|
XxlJobHelper.handleFail("script exit value("+exitValue+") is failed");
|
||||||
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,86 +0,0 @@
|
||||||
package com.xxl.job.core.log;
|
|
||||||
|
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
|
||||||
import com.xxl.job.core.util.DateUtil;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
import org.slf4j.helpers.FormattingTuple;
|
|
||||||
import org.slf4j.helpers.MessageFormatter;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
|
||||||
import java.io.StringWriter;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by xuxueli on 17/4/28.
|
|
||||||
*/
|
|
||||||
public class XxlJobLogger {
|
|
||||||
private static Logger logger = LoggerFactory.getLogger("xxl-job logger");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* append log
|
|
||||||
*
|
|
||||||
* @param callInfo
|
|
||||||
* @param appendLog
|
|
||||||
*/
|
|
||||||
private static void logDetail(StackTraceElement callInfo, String appendLog) {
|
|
||||||
|
|
||||||
|
|
||||||
/*// "yyyy-MM-dd HH:mm:ss [ClassName]-[MethodName]-[LineNumber]-[ThreadName] log";
|
|
||||||
StackTraceElement[] stackTraceElements = new Throwable().getStackTrace();
|
|
||||||
StackTraceElement callInfo = stackTraceElements[1];*/
|
|
||||||
|
|
||||||
StringBuffer stringBuffer = new StringBuffer();
|
|
||||||
stringBuffer.append(DateUtil.formatDateTime(new Date())).append(" ")
|
|
||||||
.append("["+ callInfo.getClassName() + "#" + callInfo.getMethodName() +"]").append("-")
|
|
||||||
.append("["+ callInfo.getLineNumber() +"]").append("-")
|
|
||||||
.append("["+ Thread.currentThread().getName() +"]").append(" ")
|
|
||||||
.append(appendLog!=null?appendLog:"");
|
|
||||||
String formatAppendLog = stringBuffer.toString();
|
|
||||||
|
|
||||||
// appendlog
|
|
||||||
String logFileName = XxlJobContext.getXxlJobContext().getJobLogFileName();
|
|
||||||
|
|
||||||
if (logFileName!=null && logFileName.trim().length()>0) {
|
|
||||||
XxlJobFileAppender.appendLog(logFileName, formatAppendLog);
|
|
||||||
} else {
|
|
||||||
logger.info(">>>>>>>>>>> {}", formatAppendLog);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* append log with pattern
|
|
||||||
*
|
|
||||||
* @param appendLogPattern like "aaa {} bbb {} ccc"
|
|
||||||
* @param appendLogArguments like "111, true"
|
|
||||||
*/
|
|
||||||
public static void log(String appendLogPattern, Object ... appendLogArguments) {
|
|
||||||
|
|
||||||
FormattingTuple ft = MessageFormatter.arrayFormat(appendLogPattern, appendLogArguments);
|
|
||||||
String appendLog = ft.getMessage();
|
|
||||||
|
|
||||||
/*appendLog = appendLogPattern;
|
|
||||||
if (appendLogArguments!=null && appendLogArguments.length>0) {
|
|
||||||
appendLog = MessageFormat.format(appendLogPattern, appendLogArguments);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
StackTraceElement callInfo = new Throwable().getStackTrace()[1];
|
|
||||||
logDetail(callInfo, appendLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* append exception stack
|
|
||||||
*
|
|
||||||
* @param e
|
|
||||||
*/
|
|
||||||
public static void log(Throwable e) {
|
|
||||||
|
|
||||||
StringWriter stringWriter = new StringWriter();
|
|
||||||
e.printStackTrace(new PrintWriter(stringWriter));
|
|
||||||
String appendLog = stringWriter.toString();
|
|
||||||
|
|
||||||
StackTraceElement callInfo = new Throwable().getStackTrace()[1];
|
|
||||||
logDetail(callInfo, appendLog);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -4,10 +4,10 @@ import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.biz.model.TriggerParam;
|
import com.xxl.job.core.biz.model.TriggerParam;
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
import com.xxl.job.core.context.XxlJobContext;
|
||||||
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
import com.xxl.job.core.handler.IJobHandler;
|
||||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@ -106,7 +106,6 @@ public class JobThread extends Thread{
|
||||||
idleTimes++;
|
idleTimes++;
|
||||||
|
|
||||||
TriggerParam triggerParam = null;
|
TriggerParam triggerParam = null;
|
||||||
ReturnT<String> executeResult = null;
|
|
||||||
try {
|
try {
|
||||||
// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
|
// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
|
||||||
triggerParam = triggerQueue.poll(3L, TimeUnit.SECONDS);
|
triggerParam = triggerQueue.poll(3L, TimeUnit.SECONDS);
|
||||||
|
@ -117,54 +116,68 @@ public class JobThread extends Thread{
|
||||||
|
|
||||||
// log filename, like "logPath/yyyy-MM-dd/9999.log"
|
// log filename, like "logPath/yyyy-MM-dd/9999.log"
|
||||||
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(triggerParam.getLogDateTime()), triggerParam.getLogId());
|
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(triggerParam.getLogDateTime()), triggerParam.getLogId());
|
||||||
XxlJobContext.setXxlJobContext(new XxlJobContext(
|
XxlJobContext xxlJobContext = new XxlJobContext(
|
||||||
triggerParam.getJobId(),
|
triggerParam.getJobId(),
|
||||||
|
triggerParam.getExecutorParams(),
|
||||||
logFileName,
|
logFileName,
|
||||||
triggerParam.getBroadcastIndex(),
|
triggerParam.getBroadcastIndex(),
|
||||||
triggerParam.getBroadcastTotal()));
|
triggerParam.getBroadcastTotal());
|
||||||
|
|
||||||
|
// init job context
|
||||||
|
XxlJobContext.setXxlJobContext(xxlJobContext);
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
XxlJobLogger.log("<br>----------- xxl-job job execute start -----------<br>----------- Param:" + triggerParam.getExecutorParams());
|
XxlJobHelper.log("<br>----------- xxl-job job execute start -----------<br>----------- Param:" + xxlJobContext.getJobParam());
|
||||||
|
|
||||||
if (triggerParam.getExecutorTimeout() > 0) {
|
if (triggerParam.getExecutorTimeout() > 0) {
|
||||||
// limit timeout
|
// limit timeout
|
||||||
Thread futureThread = null;
|
Thread futureThread = null;
|
||||||
try {
|
try {
|
||||||
final TriggerParam triggerParamTmp = triggerParam;
|
FutureTask<Boolean> futureTask = new FutureTask<Boolean>(new Callable<Boolean>() {
|
||||||
FutureTask<ReturnT<String>> futureTask = new FutureTask<ReturnT<String>>(new Callable<ReturnT<String>>() {
|
|
||||||
@Override
|
@Override
|
||||||
public ReturnT<String> call() throws Exception {
|
public Boolean call() throws Exception {
|
||||||
return handler.execute(triggerParamTmp.getExecutorParams());
|
|
||||||
|
// init job context
|
||||||
|
XxlJobContext.setXxlJobContext(xxlJobContext);
|
||||||
|
|
||||||
|
handler.execute();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
futureThread = new Thread(futureTask);
|
futureThread = new Thread(futureTask);
|
||||||
futureThread.start();
|
futureThread.start();
|
||||||
|
|
||||||
executeResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
|
Boolean tempResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
|
||||||
} catch (TimeoutException e) {
|
} catch (TimeoutException e) {
|
||||||
|
|
||||||
XxlJobLogger.log("<br>----------- xxl-job job execute timeout");
|
XxlJobHelper.log("<br>----------- xxl-job job execute timeout");
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
|
|
||||||
executeResult = new ReturnT<String>(IJobHandler.FAIL_TIMEOUT.getCode(), "job execute timeout ");
|
// handle result
|
||||||
|
XxlJobHelper.handleTimeout("job execute timeout ");
|
||||||
} finally {
|
} finally {
|
||||||
futureThread.interrupt();
|
futureThread.interrupt();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// just execute
|
// just execute
|
||||||
executeResult = handler.execute(triggerParam.getExecutorParams());
|
handler.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (executeResult == null) {
|
// valid execute handle data
|
||||||
executeResult = IJobHandler.FAIL;
|
if (XxlJobContext.getXxlJobContext().getHandleCode() <= 0) {
|
||||||
|
XxlJobHelper.handleFail("job handle result lost.");
|
||||||
} else {
|
} else {
|
||||||
executeResult.setMsg(
|
String tempHandleMsg = XxlJobContext.getXxlJobContext().getHandleMsg();
|
||||||
(executeResult!=null&&executeResult.getMsg()!=null&&executeResult.getMsg().length()>50000)
|
tempHandleMsg = (tempHandleMsg!=null&&tempHandleMsg.length()>50000)
|
||||||
?executeResult.getMsg().substring(0, 50000).concat("...")
|
?tempHandleMsg.substring(0, 50000).concat("...")
|
||||||
:executeResult.getMsg());
|
:tempHandleMsg;
|
||||||
executeResult.setContent(null); // limit obj size
|
XxlJobContext.getXxlJobContext().setHandleMsg(tempHandleMsg);
|
||||||
}
|
}
|
||||||
XxlJobLogger.log("<br>----------- xxl-job job execute end(finish) -----------<br>----------- ReturnT:" + executeResult);
|
XxlJobHelper.log("<br>----------- xxl-job job execute end(finish) -----------<br>----------- Result: handleCode="
|
||||||
|
+ XxlJobContext.getXxlJobContext().getHandleCode()
|
||||||
|
+ ", handleMsg = "
|
||||||
|
+ XxlJobContext.getXxlJobContext().getHandleMsg()
|
||||||
|
);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (idleTimes > 30) {
|
if (idleTimes > 30) {
|
||||||
|
@ -175,25 +188,36 @@ public class JobThread extends Thread{
|
||||||
}
|
}
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (toStop) {
|
if (toStop) {
|
||||||
XxlJobLogger.log("<br>----------- JobThread toStop, stopReason:" + stopReason);
|
XxlJobHelper.log("<br>----------- JobThread toStop, stopReason:" + stopReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// handle result
|
||||||
StringWriter stringWriter = new StringWriter();
|
StringWriter stringWriter = new StringWriter();
|
||||||
e.printStackTrace(new PrintWriter(stringWriter));
|
e.printStackTrace(new PrintWriter(stringWriter));
|
||||||
String errorMsg = stringWriter.toString();
|
String errorMsg = stringWriter.toString();
|
||||||
executeResult = new ReturnT<String>(ReturnT.FAIL_CODE, errorMsg);
|
|
||||||
|
|
||||||
XxlJobLogger.log("<br>----------- JobThread Exception:" + errorMsg + "<br>----------- xxl-job job execute end(error) -----------");
|
XxlJobHelper.handleFail(errorMsg);
|
||||||
|
|
||||||
|
XxlJobHelper.log("<br>----------- JobThread Exception:" + errorMsg + "<br>----------- xxl-job job execute end(error) -----------");
|
||||||
} finally {
|
} finally {
|
||||||
if(triggerParam != null) {
|
if(triggerParam != null) {
|
||||||
// callback handler info
|
// callback handler info
|
||||||
if (!toStop) {
|
if (!toStop) {
|
||||||
// commonm
|
// commonm
|
||||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTime(), executeResult));
|
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(
|
||||||
|
triggerParam.getLogId(),
|
||||||
|
triggerParam.getLogDateTime(),
|
||||||
|
XxlJobContext.getXxlJobContext().getHandleCode(),
|
||||||
|
XxlJobContext.getXxlJobContext().getHandleMsg() )
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// is killed
|
// is killed
|
||||||
ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [job running, killed]");
|
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(
|
||||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTime(), stopResult));
|
triggerParam.getLogId(),
|
||||||
|
triggerParam.getLogDateTime(),
|
||||||
|
XxlJobContext.HANDLE_COCE_FAIL,
|
||||||
|
stopReason + " [job running, killed]" )
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,8 +228,12 @@ public class JobThread extends Thread{
|
||||||
TriggerParam triggerParam = triggerQueue.poll();
|
TriggerParam triggerParam = triggerQueue.poll();
|
||||||
if (triggerParam!=null) {
|
if (triggerParam!=null) {
|
||||||
// is killed
|
// is killed
|
||||||
ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [job not executed, in the job queue, killed.]");
|
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(
|
||||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTime(), stopResult));
|
triggerParam.getLogId(),
|
||||||
|
triggerParam.getLogDateTime(),
|
||||||
|
XxlJobContext.HANDLE_COCE_FAIL,
|
||||||
|
stopReason + " [job not executed, in the job queue, killed.]")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,10 @@ import com.xxl.job.core.biz.AdminBiz;
|
||||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.biz.model.ReturnT;
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
import com.xxl.job.core.context.XxlJobContext;
|
||||||
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.enums.RegistryConfig;
|
import com.xxl.job.core.enums.RegistryConfig;
|
||||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
import com.xxl.job.core.util.FileUtil;
|
import com.xxl.job.core.util.FileUtil;
|
||||||
import com.xxl.job.core.util.JdkSerializeTool;
|
import com.xxl.job.core.util.JdkSerializeTool;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -190,10 +190,11 @@ public class TriggerCallbackThread {
|
||||||
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(callbackParam.getLogDateTim()), callbackParam.getLogId());
|
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(callbackParam.getLogDateTim()), callbackParam.getLogId());
|
||||||
XxlJobContext.setXxlJobContext(new XxlJobContext(
|
XxlJobContext.setXxlJobContext(new XxlJobContext(
|
||||||
-1,
|
-1,
|
||||||
|
null,
|
||||||
logFileName,
|
logFileName,
|
||||||
-1,
|
-1,
|
||||||
-1));
|
-1));
|
||||||
XxlJobLogger.log(logContent);
|
XxlJobHelper.log(logContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.xxl.job.core.util;
|
package com.xxl.job.core.util;
|
||||||
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -83,7 +83,7 @@ public class ScriptUtil {
|
||||||
try {
|
try {
|
||||||
copy(process.getInputStream(), finalFileOutputStream, new byte[1024]);
|
copy(process.getInputStream(), finalFileOutputStream, new byte[1024]);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -93,7 +93,7 @@ public class ScriptUtil {
|
||||||
try {
|
try {
|
||||||
copy(process.getErrorStream(), finalFileOutputStream, new byte[1024]);
|
copy(process.getErrorStream(), finalFileOutputStream, new byte[1024]);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -109,14 +109,14 @@ public class ScriptUtil {
|
||||||
|
|
||||||
return exitValue;
|
return exitValue;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
return -1;
|
return -1;
|
||||||
} finally {
|
} finally {
|
||||||
if (fileOutputStream != null) {
|
if (fileOutputStream != null) {
|
||||||
try {
|
try {
|
||||||
fileOutputStream.close();
|
fileOutputStream.close();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
<module>xxl-job-executor-sample-frameless</module>
|
<module>xxl-job-executor-sample-frameless</module>
|
||||||
<module>xxl-job-executor-sample-springboot</module>
|
<module>xxl-job-executor-sample-springboot</module>
|
||||||
<module>xxl-job-executor-sample-spring</module>
|
<module>xxl-job-executor-sample-spring</module>
|
||||||
<module>xxl-job-executor-sample-jfinal</module>
|
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -1,54 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.frameless.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 命令行任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2018-09-16 03:48:34
|
|
||||||
*/
|
|
||||||
public class CommandJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
String command = param;
|
|
||||||
int exitValue = -1;
|
|
||||||
|
|
||||||
BufferedReader bufferedReader = null;
|
|
||||||
try {
|
|
||||||
// command process
|
|
||||||
Process process = Runtime.getRuntime().exec(command);
|
|
||||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
|
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
|
||||||
|
|
||||||
// command log
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
XxlJobLogger.log(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// command exit
|
|
||||||
process.waitFor();
|
|
||||||
exitValue = process.exitValue();
|
|
||||||
} catch (Exception e) {
|
|
||||||
XxlJobLogger.log(e);
|
|
||||||
} finally {
|
|
||||||
if (bufferedReader != null) {
|
|
||||||
bufferedReader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exitValue == 0) {
|
|
||||||
return IJobHandler.SUCCESS;
|
|
||||||
} else {
|
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.frameless.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务Handler示例(Bean模式)
|
|
||||||
*
|
|
||||||
* 开发步骤:
|
|
||||||
* 1、继承"IJobHandler":“com.xxl.job.core.handler.IJobHandler”;
|
|
||||||
* 2、注册到执行器工厂:在 "JFinalCoreConfig.initXxlJobExecutor" 中手动注册,注解key值对应的是调度中心新建任务的JobHandler属性的值。
|
|
||||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
|
||||||
*
|
|
||||||
* @author xuxueli 2015-12-19 19:43:36
|
|
||||||
*/
|
|
||||||
public class DemoJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
XxlJobLogger.log("beat at:" + i);
|
|
||||||
TimeUnit.SECONDS.sleep(2);
|
|
||||||
}
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.frameless.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跨平台Http任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2018-09-16 03:48:34
|
|
||||||
*/
|
|
||||||
public class HttpJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
|
|
||||||
// param parse
|
|
||||||
if (param==null || param.trim().length()==0) {
|
|
||||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
String[] httpParams = param.split("\n");
|
|
||||||
String url = null;
|
|
||||||
String method = null;
|
|
||||||
String data = null;
|
|
||||||
for (String httpParam: httpParams) {
|
|
||||||
if (httpParam.startsWith("url:")) {
|
|
||||||
url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
|
|
||||||
}
|
|
||||||
if (httpParam.startsWith("method:")) {
|
|
||||||
method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
|
|
||||||
}
|
|
||||||
if (httpParam.startsWith("data:")) {
|
|
||||||
data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// param valid
|
|
||||||
if (url==null || url.trim().length()==0) {
|
|
||||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
|
||||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
boolean isPostMethod = method.equals("POST");
|
|
||||||
|
|
||||||
// request
|
|
||||||
HttpURLConnection connection = null;
|
|
||||||
BufferedReader bufferedReader = null;
|
|
||||||
try {
|
|
||||||
// connection
|
|
||||||
URL realUrl = new URL(url);
|
|
||||||
connection = (HttpURLConnection) realUrl.openConnection();
|
|
||||||
|
|
||||||
// connection setting
|
|
||||||
connection.setRequestMethod(method);
|
|
||||||
connection.setDoOutput(isPostMethod);
|
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
connection.setReadTimeout(5 * 1000);
|
|
||||||
connection.setConnectTimeout(3 * 1000);
|
|
||||||
connection.setRequestProperty("connection", "Keep-Alive");
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
|
||||||
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
|
|
||||||
|
|
||||||
// do connection
|
|
||||||
connection.connect();
|
|
||||||
|
|
||||||
// data
|
|
||||||
if (isPostMethod && data!=null && data.trim().length()>0) {
|
|
||||||
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
|
|
||||||
dataOutputStream.write(data.getBytes("UTF-8"));
|
|
||||||
dataOutputStream.flush();
|
|
||||||
dataOutputStream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid StatusCode
|
|
||||||
int statusCode = connection.getResponseCode();
|
|
||||||
if (statusCode != 200) {
|
|
||||||
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// result
|
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
result.append(line);
|
|
||||||
}
|
|
||||||
String responseMsg = result.toString();
|
|
||||||
|
|
||||||
XxlJobLogger.log(responseMsg);
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
} catch (Exception e) {
|
|
||||||
XxlJobLogger.log(e);
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (bufferedReader != null) {
|
|
||||||
bufferedReader.close();
|
|
||||||
}
|
|
||||||
if (connection != null) {
|
|
||||||
connection.disconnect();
|
|
||||||
}
|
|
||||||
} catch (Exception e2) {
|
|
||||||
XxlJobLogger.log(e2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.frameless.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分片广播任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2017-07-25 20:56:50
|
|
||||||
*/
|
|
||||||
public class ShardingJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
|
|
||||||
// 分片参数
|
|
||||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
|
||||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
|
||||||
|
|
||||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
|
||||||
|
|
||||||
// 业务逻辑
|
|
||||||
for (int i = 0; i < shardTotal; i++) {
|
|
||||||
if (i == shardIndex) {
|
|
||||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
|
||||||
} else {
|
|
||||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.xuxueli.executor.sample.frameless;
|
package com.xxl.job.executor.sample.frameless;
|
||||||
|
|
||||||
import com.xuxueli.executor.sample.frameless.config.FrameLessXxlJobConfig;
|
import com.xxl.job.executor.sample.frameless.config.FrameLessXxlJobConfig;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
|
@ -1,15 +1,13 @@
|
||||||
package com.xuxueli.executor.sample.frameless.config;
|
package com.xxl.job.executor.sample.frameless.config;
|
||||||
|
|
||||||
import com.xuxueli.executor.sample.frameless.jobhandler.CommandJobHandler;
|
import com.xxl.job.executor.sample.frameless.jobhandler.SampleXxlJob;
|
||||||
import com.xuxueli.executor.sample.frameless.jobhandler.DemoJobHandler;
|
import com.xxl.job.core.executor.impl.XxlJobSimpleExecutor;
|
||||||
import com.xuxueli.executor.sample.frameless.jobhandler.HttpJobHandler;
|
|
||||||
import com.xuxueli.executor.sample.frameless.jobhandler.ShardingJobHandler;
|
|
||||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,25 +23,18 @@ public class FrameLessXxlJobConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private XxlJobExecutor xxlJobExecutor = null;
|
private XxlJobSimpleExecutor xxlJobExecutor = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init
|
* init
|
||||||
*/
|
*/
|
||||||
public void initXxlJobExecutor() {
|
public void initXxlJobExecutor() {
|
||||||
|
|
||||||
// registry jobhandler
|
|
||||||
XxlJobExecutor.registJobHandler("demoJobHandler", new DemoJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("shardingJobHandler", new ShardingJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("httpJobHandler", new HttpJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("commandJobHandler", new CommandJobHandler());
|
|
||||||
|
|
||||||
// load executor prop
|
// load executor prop
|
||||||
Properties xxlJobProp = loadProperties("xxl-job-executor.properties");
|
Properties xxlJobProp = loadProperties("xxl-job-executor.properties");
|
||||||
|
|
||||||
|
|
||||||
// init executor
|
// init executor
|
||||||
xxlJobExecutor = new XxlJobExecutor();
|
xxlJobExecutor = new XxlJobSimpleExecutor();
|
||||||
xxlJobExecutor.setAdminAddresses(xxlJobProp.getProperty("xxl.job.admin.addresses"));
|
xxlJobExecutor.setAdminAddresses(xxlJobProp.getProperty("xxl.job.admin.addresses"));
|
||||||
xxlJobExecutor.setAccessToken(xxlJobProp.getProperty("xxl.job.accessToken"));
|
xxlJobExecutor.setAccessToken(xxlJobProp.getProperty("xxl.job.accessToken"));
|
||||||
xxlJobExecutor.setAppname(xxlJobProp.getProperty("xxl.job.executor.appname"));
|
xxlJobExecutor.setAppname(xxlJobProp.getProperty("xxl.job.executor.appname"));
|
||||||
|
@ -53,6 +44,9 @@ public class FrameLessXxlJobConfig {
|
||||||
xxlJobExecutor.setLogPath(xxlJobProp.getProperty("xxl.job.executor.logpath"));
|
xxlJobExecutor.setLogPath(xxlJobProp.getProperty("xxl.job.executor.logpath"));
|
||||||
xxlJobExecutor.setLogRetentionDays(Integer.valueOf(xxlJobProp.getProperty("xxl.job.executor.logretentiondays")));
|
xxlJobExecutor.setLogRetentionDays(Integer.valueOf(xxlJobProp.getProperty("xxl.job.executor.logretentiondays")));
|
||||||
|
|
||||||
|
// registry job bean
|
||||||
|
xxlJobExecutor.setXxlJobBeanList(Arrays.asList(new SampleXxlJob()));
|
||||||
|
|
||||||
// start executor
|
// start executor
|
||||||
try {
|
try {
|
||||||
xxlJobExecutor.start();
|
xxlJobExecutor.start();
|
|
@ -0,0 +1,251 @@
|
||||||
|
package com.xxl.job.executor.sample.frameless.jobhandler;
|
||||||
|
|
||||||
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.BufferedInputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.net.HttpURLConnection;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XxlJob开发示例(Bean模式)
|
||||||
|
*
|
||||||
|
* 开发步骤:
|
||||||
|
* 1、任务开发:在Spring Bean实例中,开发Job方法;
|
||||||
|
* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
||||||
|
* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;
|
||||||
|
* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;
|
||||||
|
*
|
||||||
|
* @author xuxueli 2019-12-11 21:52:51
|
||||||
|
*/
|
||||||
|
public class SampleXxlJob {
|
||||||
|
private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 1、简单任务示例(Bean模式)
|
||||||
|
*/
|
||||||
|
@XxlJob("demoJobHandler")
|
||||||
|
public void demoJobHandler() throws Exception {
|
||||||
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
XxlJobHelper.log("beat at:" + i);
|
||||||
|
TimeUnit.SECONDS.sleep(2);
|
||||||
|
}
|
||||||
|
// default success
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 2、分片广播任务
|
||||||
|
*/
|
||||||
|
@XxlJob("shardingJobHandler")
|
||||||
|
public void shardingJobHandler() throws Exception {
|
||||||
|
|
||||||
|
// 分片参数
|
||||||
|
int shardIndex = XxlJobHelper.getShardIndex();
|
||||||
|
int shardTotal = XxlJobHelper.getShardTotal();
|
||||||
|
|
||||||
|
XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||||
|
|
||||||
|
// 业务逻辑
|
||||||
|
for (int i = 0; i < shardTotal; i++) {
|
||||||
|
if (i == shardIndex) {
|
||||||
|
XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
|
||||||
|
} else {
|
||||||
|
XxlJobHelper.log("第 {} 片, 忽略", i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3、命令行任务
|
||||||
|
*/
|
||||||
|
@XxlJob("commandJobHandler")
|
||||||
|
public void commandJobHandler() throws Exception {
|
||||||
|
String command = XxlJobHelper.getJobParam();
|
||||||
|
int exitValue = -1;
|
||||||
|
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
try {
|
||||||
|
// command process
|
||||||
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.command(command);
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
//Process process = Runtime.getRuntime().exec(command);
|
||||||
|
|
||||||
|
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
||||||
|
|
||||||
|
// command log
|
||||||
|
String line;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
XxlJobHelper.log(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
// command exit
|
||||||
|
process.waitFor();
|
||||||
|
exitValue = process.exitValue();
|
||||||
|
} catch (Exception e) {
|
||||||
|
XxlJobHelper.log(e);
|
||||||
|
} finally {
|
||||||
|
if (bufferedReader != null) {
|
||||||
|
bufferedReader.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (exitValue == 0) {
|
||||||
|
// default success
|
||||||
|
} else {
|
||||||
|
XxlJobHelper.handleFail("command exit value("+exitValue+") is failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 4、跨平台Http任务
|
||||||
|
* 参数示例:
|
||||||
|
* "url: http://www.baidu.com\n" +
|
||||||
|
* "method: get\n" +
|
||||||
|
* "data: content\n";
|
||||||
|
*/
|
||||||
|
@XxlJob("httpJobHandler")
|
||||||
|
public void httpJobHandler() throws Exception {
|
||||||
|
|
||||||
|
// param parse
|
||||||
|
String param = XxlJobHelper.getJobParam();
|
||||||
|
if (param==null || param.trim().length()==0) {
|
||||||
|
XxlJobHelper.log("param["+ param +"] invalid.");
|
||||||
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] httpParams = param.split("\n");
|
||||||
|
String url = null;
|
||||||
|
String method = null;
|
||||||
|
String data = null;
|
||||||
|
for (String httpParam: httpParams) {
|
||||||
|
if (httpParam.startsWith("url:")) {
|
||||||
|
url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
|
||||||
|
}
|
||||||
|
if (httpParam.startsWith("method:")) {
|
||||||
|
method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
|
||||||
|
}
|
||||||
|
if (httpParam.startsWith("data:")) {
|
||||||
|
data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// param valid
|
||||||
|
if (url==null || url.trim().length()==0) {
|
||||||
|
XxlJobHelper.log("url["+ url +"] invalid.");
|
||||||
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
||||||
|
XxlJobHelper.log("method["+ method +"] invalid.");
|
||||||
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
boolean isPostMethod = method.equals("POST");
|
||||||
|
|
||||||
|
// request
|
||||||
|
HttpURLConnection connection = null;
|
||||||
|
BufferedReader bufferedReader = null;
|
||||||
|
try {
|
||||||
|
// connection
|
||||||
|
URL realUrl = new URL(url);
|
||||||
|
connection = (HttpURLConnection) realUrl.openConnection();
|
||||||
|
|
||||||
|
// connection setting
|
||||||
|
connection.setRequestMethod(method);
|
||||||
|
connection.setDoOutput(isPostMethod);
|
||||||
|
connection.setDoInput(true);
|
||||||
|
connection.setUseCaches(false);
|
||||||
|
connection.setReadTimeout(5 * 1000);
|
||||||
|
connection.setConnectTimeout(3 * 1000);
|
||||||
|
connection.setRequestProperty("connection", "Keep-Alive");
|
||||||
|
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
||||||
|
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
|
||||||
|
|
||||||
|
// do connection
|
||||||
|
connection.connect();
|
||||||
|
|
||||||
|
// data
|
||||||
|
if (isPostMethod && data!=null && data.trim().length()>0) {
|
||||||
|
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
|
||||||
|
dataOutputStream.write(data.getBytes("UTF-8"));
|
||||||
|
dataOutputStream.flush();
|
||||||
|
dataOutputStream.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
// valid StatusCode
|
||||||
|
int statusCode = connection.getResponseCode();
|
||||||
|
if (statusCode != 200) {
|
||||||
|
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// result
|
||||||
|
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
|
result.append(line);
|
||||||
|
}
|
||||||
|
String responseMsg = result.toString();
|
||||||
|
|
||||||
|
XxlJobHelper.log(responseMsg);
|
||||||
|
|
||||||
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
XxlJobHelper.log(e);
|
||||||
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (bufferedReader != null) {
|
||||||
|
bufferedReader.close();
|
||||||
|
}
|
||||||
|
if (connection != null) {
|
||||||
|
connection.disconnect();
|
||||||
|
}
|
||||||
|
} catch (Exception e2) {
|
||||||
|
XxlJobHelper.log(e2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
||||||
|
*/
|
||||||
|
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
||||||
|
public void demoJobHandler2() throws Exception {
|
||||||
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
|
}
|
||||||
|
public void init(){
|
||||||
|
logger.info("init");
|
||||||
|
}
|
||||||
|
public void destroy(){
|
||||||
|
logger.info("destory");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -10,7 +10,7 @@ xxl.job.executor.appname=xxl-job-executor-sample
|
||||||
xxl.job.executor.address=
|
xxl.job.executor.address=
|
||||||
### xxl-job executor server-info
|
### xxl-job executor server-info
|
||||||
xxl.job.executor.ip=
|
xxl.job.executor.ip=
|
||||||
xxl.job.executor.port=9999
|
xxl.job.executor.port=9998
|
||||||
### xxl-job executor log-path
|
### xxl-job executor log-path
|
||||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
||||||
### xxl-job executor log-retention-days
|
### xxl-job executor log-retention-days
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<groupId>com.xuxueli</groupId>
|
|
||||||
<artifactId>xxl-job-executor-samples</artifactId>
|
|
||||||
<version>2.3.0-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>xxl-job-executor-sample-jfinal</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<!-- jfinal -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jfinal</groupId>
|
|
||||||
<artifactId>jfinal-undertow</artifactId>
|
|
||||||
<version>2.2</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jfinal</groupId>
|
|
||||||
<artifactId>jfinal</artifactId>
|
|
||||||
<version>4.9.02</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- slf4j -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-log4j12</artifactId>
|
|
||||||
<version>${slf4j-api.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- xxl-job -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.xuxueli</groupId>
|
|
||||||
<artifactId>xxl-job-core</artifactId>
|
|
||||||
<version>${project.parent.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
|
@ -1,12 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal;
|
|
||||||
|
|
||||||
import com.jfinal.server.undertow.UndertowServer;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.config.JFinalCoreConfig;
|
|
||||||
|
|
||||||
public class XxlJobExecutorApplication {
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
UndertowServer.start(JFinalCoreConfig.class, 8082, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,85 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.config;
|
|
||||||
|
|
||||||
import com.jfinal.config.*;
|
|
||||||
import com.jfinal.kit.Prop;
|
|
||||||
import com.jfinal.kit.PropKit;
|
|
||||||
import com.jfinal.template.Engine;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.controller.IndexController;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.jobhandler.CommandJobHandler;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.jobhandler.DemoJobHandler;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.jobhandler.HttpJobHandler;
|
|
||||||
import com.xuxueli.executor.sample.jfinal.jobhandler.ShardingJobHandler;
|
|
||||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author xuxueli 2017-08-11 14:17:41
|
|
||||||
*/
|
|
||||||
public class JFinalCoreConfig extends JFinalConfig {
|
|
||||||
private Logger logger = LoggerFactory.getLogger(JFinalCoreConfig.class);
|
|
||||||
|
|
||||||
// ---------------------- xxl-job executor ----------------------
|
|
||||||
private XxlJobExecutor xxlJobExecutor = null;
|
|
||||||
private void initXxlJobExecutor() {
|
|
||||||
|
|
||||||
// registry jobhandler
|
|
||||||
XxlJobExecutor.registJobHandler("demoJobHandler", new DemoJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("shardingJobHandler", new ShardingJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("httpJobHandler", new HttpJobHandler());
|
|
||||||
XxlJobExecutor.registJobHandler("commandJobHandler", new CommandJobHandler());
|
|
||||||
|
|
||||||
// load executor prop
|
|
||||||
Prop xxlJobProp = PropKit.use("xxl-job-executor.properties");
|
|
||||||
|
|
||||||
// init executor
|
|
||||||
xxlJobExecutor = new XxlJobExecutor();
|
|
||||||
xxlJobExecutor.setAdminAddresses(xxlJobProp.get("xxl.job.admin.addresses"));
|
|
||||||
xxlJobExecutor.setAccessToken(xxlJobProp.get("xxl.job.accessToken"));
|
|
||||||
xxlJobExecutor.setAddress(xxlJobProp.get("xxl.job.executor.address"));
|
|
||||||
xxlJobExecutor.setAppname(xxlJobProp.get("xxl.job.executor.appname"));
|
|
||||||
xxlJobExecutor.setIp(xxlJobProp.get("xxl.job.executor.ip"));
|
|
||||||
xxlJobExecutor.setPort(xxlJobProp.getInt("xxl.job.executor.port"));
|
|
||||||
|
|
||||||
xxlJobExecutor.setLogPath(xxlJobProp.get("xxl.job.executor.logpath"));
|
|
||||||
xxlJobExecutor.setLogRetentionDays(xxlJobProp.getInt("xxl.job.executor.logretentiondays"));
|
|
||||||
|
|
||||||
// start executor
|
|
||||||
try {
|
|
||||||
xxlJobExecutor.start();
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.error(e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private void destoryXxlJobExecutor() {
|
|
||||||
if (xxlJobExecutor != null) {
|
|
||||||
xxlJobExecutor.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------- jfinal ----------------------
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStart() {
|
|
||||||
initXxlJobExecutor();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStop() {
|
|
||||||
destoryXxlJobExecutor();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void configConstant(Constants me) {
|
|
||||||
me.setDevMode(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void configRoute(Routes routes) {
|
|
||||||
routes.add("/", IndexController.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void configEngine(Engine me) {}
|
|
||||||
public void configPlugin(Plugins me) {}
|
|
||||||
public void configInterceptor(Interceptors me) {}
|
|
||||||
public void configHandler(Handlers me) {}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.controller;
|
|
||||||
|
|
||||||
import com.jfinal.core.Controller;
|
|
||||||
|
|
||||||
public class IndexController extends Controller {
|
|
||||||
|
|
||||||
public void index(){
|
|
||||||
renderText("xxl job executor running.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,54 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 命令行任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2018-09-16 03:48:34
|
|
||||||
*/
|
|
||||||
public class CommandJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
String command = param;
|
|
||||||
int exitValue = -1;
|
|
||||||
|
|
||||||
BufferedReader bufferedReader = null;
|
|
||||||
try {
|
|
||||||
// command process
|
|
||||||
Process process = Runtime.getRuntime().exec(command);
|
|
||||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
|
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
|
||||||
|
|
||||||
// command log
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
XxlJobLogger.log(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
// command exit
|
|
||||||
process.waitFor();
|
|
||||||
exitValue = process.exitValue();
|
|
||||||
} catch (Exception e) {
|
|
||||||
XxlJobLogger.log(e);
|
|
||||||
} finally {
|
|
||||||
if (bufferedReader != null) {
|
|
||||||
bufferedReader.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (exitValue == 0) {
|
|
||||||
return IJobHandler.SUCCESS;
|
|
||||||
} else {
|
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,32 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 任务Handler示例(Bean模式)
|
|
||||||
*
|
|
||||||
* 开发步骤:
|
|
||||||
* 1、继承"IJobHandler":“com.xxl.job.core.handler.IJobHandler”;
|
|
||||||
* 2、注册到执行器工厂:在 "JFinalCoreConfig.initXxlJobExecutor" 中手动注册,注解key值对应的是调度中心新建任务的JobHandler属性的值。
|
|
||||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
|
||||||
*
|
|
||||||
* @author xuxueli 2015-12-19 19:43:36
|
|
||||||
*/
|
|
||||||
public class DemoJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
XxlJobLogger.log("beat at:" + i);
|
|
||||||
TimeUnit.SECONDS.sleep(2);
|
|
||||||
}
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,121 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
|
||||||
import java.io.DataOutputStream;
|
|
||||||
import java.io.InputStreamReader;
|
|
||||||
import java.net.HttpURLConnection;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 跨平台Http任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2018-09-16 03:48:34
|
|
||||||
*/
|
|
||||||
public class HttpJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
|
|
||||||
// param parse
|
|
||||||
if (param==null || param.trim().length()==0) {
|
|
||||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
String[] httpParams = param.split("\n");
|
|
||||||
String url = null;
|
|
||||||
String method = null;
|
|
||||||
String data = null;
|
|
||||||
for (String httpParam: httpParams) {
|
|
||||||
if (httpParam.startsWith("url:")) {
|
|
||||||
url = httpParam.substring(httpParam.indexOf("url:") + 4).trim();
|
|
||||||
}
|
|
||||||
if (httpParam.startsWith("method:")) {
|
|
||||||
method = httpParam.substring(httpParam.indexOf("method:") + 7).trim().toUpperCase();
|
|
||||||
}
|
|
||||||
if (httpParam.startsWith("data:")) {
|
|
||||||
data = httpParam.substring(httpParam.indexOf("data:") + 5).trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// param valid
|
|
||||||
if (url==null || url.trim().length()==0) {
|
|
||||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
|
||||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
}
|
|
||||||
boolean isPostMethod = method.equals("POST");
|
|
||||||
|
|
||||||
// request
|
|
||||||
HttpURLConnection connection = null;
|
|
||||||
BufferedReader bufferedReader = null;
|
|
||||||
try {
|
|
||||||
// connection
|
|
||||||
URL realUrl = new URL(url);
|
|
||||||
connection = (HttpURLConnection) realUrl.openConnection();
|
|
||||||
|
|
||||||
// connection setting
|
|
||||||
connection.setRequestMethod(method);
|
|
||||||
connection.setDoOutput(isPostMethod);
|
|
||||||
connection.setDoInput(true);
|
|
||||||
connection.setUseCaches(false);
|
|
||||||
connection.setReadTimeout(5 * 1000);
|
|
||||||
connection.setConnectTimeout(3 * 1000);
|
|
||||||
connection.setRequestProperty("connection", "Keep-Alive");
|
|
||||||
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
|
||||||
connection.setRequestProperty("Accept-Charset", "application/json;charset=UTF-8");
|
|
||||||
|
|
||||||
// do connection
|
|
||||||
connection.connect();
|
|
||||||
|
|
||||||
// data
|
|
||||||
if (isPostMethod && data!=null && data.trim().length()>0) {
|
|
||||||
DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
|
|
||||||
dataOutputStream.write(data.getBytes("UTF-8"));
|
|
||||||
dataOutputStream.flush();
|
|
||||||
dataOutputStream.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// valid StatusCode
|
|
||||||
int statusCode = connection.getResponseCode();
|
|
||||||
if (statusCode != 200) {
|
|
||||||
throw new RuntimeException("Http Request StatusCode(" + statusCode + ") Invalid.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// result
|
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
|
|
||||||
StringBuilder result = new StringBuilder();
|
|
||||||
String line;
|
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
|
||||||
result.append(line);
|
|
||||||
}
|
|
||||||
String responseMsg = result.toString();
|
|
||||||
|
|
||||||
XxlJobLogger.log(responseMsg);
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
} catch (Exception e) {
|
|
||||||
XxlJobLogger.log(e);
|
|
||||||
return ReturnT.FAIL;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (bufferedReader != null) {
|
|
||||||
bufferedReader.close();
|
|
||||||
}
|
|
||||||
if (connection != null) {
|
|
||||||
connection.disconnect();
|
|
||||||
}
|
|
||||||
} catch (Exception e2) {
|
|
||||||
XxlJobLogger.log(e2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,36 +0,0 @@
|
||||||
package com.xuxueli.executor.sample.jfinal.jobhandler;
|
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分片广播任务
|
|
||||||
*
|
|
||||||
* @author xuxueli 2017-07-25 20:56:50
|
|
||||||
*/
|
|
||||||
public class ShardingJobHandler extends IJobHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ReturnT<String> execute(String param) throws Exception {
|
|
||||||
|
|
||||||
// 分片参数
|
|
||||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
|
||||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
|
||||||
|
|
||||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
|
||||||
|
|
||||||
// 业务逻辑
|
|
||||||
for (int i = 0; i < shardTotal; i++) {
|
|
||||||
if (i == shardIndex) {
|
|
||||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
|
||||||
} else {
|
|
||||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,27 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE log4j:configuration PUBLIC "-//log4j/log4j Configuration//EN" "log4j.dtd">
|
|
||||||
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" threshold="null" debug="null">
|
|
||||||
|
|
||||||
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
|
|
||||||
<param name="Target" value="System.out" />
|
|
||||||
<layout class="org.apache.log4j.PatternLayout">
|
|
||||||
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} xxl-job-executor-sample-jfinal [%c]-[%t]-[%M]-[%L]-[%p] %m%n"/>
|
|
||||||
</layout>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<appender name="FILE" class="org.apache.log4j.DailyRollingFileAppender">
|
|
||||||
<param name="file" value="/data/applogs/xxl-job/xxl-job-executor-sample-jfinal.log"/>
|
|
||||||
<param name="append" value="true"/>
|
|
||||||
<param name="encoding" value="UTF-8"/>
|
|
||||||
<layout class="org.apache.log4j.PatternLayout">
|
|
||||||
<param name="ConversionPattern" value="%-d{yyyy-MM-dd HH:mm:ss} xxl-job-executor-sample-jfinal [%c]-[%t]-[%M]-[%L]-[%p] %m%n"/>
|
|
||||||
</layout>
|
|
||||||
</appender>
|
|
||||||
|
|
||||||
<root>
|
|
||||||
<level value="INFO" />
|
|
||||||
<appender-ref ref="CONSOLE" />
|
|
||||||
<appender-ref ref="FILE" />
|
|
||||||
</root>
|
|
||||||
|
|
||||||
</log4j:configuration>
|
|
|
@ -1,17 +0,0 @@
|
||||||
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
|
|
||||||
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
|
|
||||||
|
|
||||||
### xxl-job, access token
|
|
||||||
xxl.job.accessToken=
|
|
||||||
|
|
||||||
### xxl-job executor appname
|
|
||||||
xxl.job.executor.appname=xxl-job-executor-sample
|
|
||||||
### xxl-job executor registry-address: default use address to registry , otherwise use ip:port if address is null
|
|
||||||
xxl.job.executor.address=
|
|
||||||
### xxl-job executor server-info
|
|
||||||
xxl.job.executor.ip=
|
|
||||||
xxl.job.executor.port=9999
|
|
||||||
### xxl-job executor log-path
|
|
||||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
|
||||||
### xxl-job executor log-retention-days
|
|
||||||
xxl.job.executor.logretentiondays=30
|
|
|
@ -1,32 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
|
||||||
id="WebApp_ID" version="2.5">
|
|
||||||
|
|
||||||
<display-name>xxl-job-executor-sample-jfinal</display-name>
|
|
||||||
<context-param>
|
|
||||||
<param-name>webAppRootKey</param-name>
|
|
||||||
<param-value>xxl-job-executor-sample-jfinal</param-value>
|
|
||||||
</context-param>
|
|
||||||
|
|
||||||
<!-- jfinal -->
|
|
||||||
<filter>
|
|
||||||
<filter-name>jfinal</filter-name>
|
|
||||||
<filter-class>com.jfinal.core.JFinalFilter</filter-class>
|
|
||||||
<init-param>
|
|
||||||
<param-name>configClass</param-name>
|
|
||||||
<param-value>com.xuxueli.executor.sample.jfinal.config.JFinalCoreConfig</param-value>
|
|
||||||
</init-param>
|
|
||||||
</filter>
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>jfinal</filter-name>
|
|
||||||
<url-pattern>/*</url-pattern>
|
|
||||||
</filter-mapping>
|
|
||||||
|
|
||||||
|
|
||||||
<welcome-file-list>
|
|
||||||
<welcome-file>index.html</welcome-file>
|
|
||||||
</welcome-file-list>
|
|
||||||
|
|
||||||
</web-app>
|
|
|
@ -1 +0,0 @@
|
||||||
i am alive.
|
|
|
@ -1,10 +1,7 @@
|
||||||
package com.xxl.job.executor.service.jobhandler;
|
package com.xxl.job.executor.service.jobhandler;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -22,9 +19,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
* XxlJob开发示例(Bean模式)
|
* XxlJob开发示例(Bean模式)
|
||||||
*
|
*
|
||||||
* 开发步骤:
|
* 开发步骤:
|
||||||
* 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"
|
* 1、任务开发:在Spring Bean实例中,开发Job方法;
|
||||||
* 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
||||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;
|
||||||
|
* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;
|
||||||
*
|
*
|
||||||
* @author xuxueli 2019-12-11 21:52:51
|
* @author xuxueli 2019-12-11 21:52:51
|
||||||
*/
|
*/
|
||||||
|
@ -37,14 +35,14 @@ public class SampleXxlJob {
|
||||||
* 1、简单任务示例(Bean模式)
|
* 1、简单任务示例(Bean模式)
|
||||||
*/
|
*/
|
||||||
@XxlJob("demoJobHandler")
|
@XxlJob("demoJobHandler")
|
||||||
public ReturnT<String> demoJobHandler(String param) throws Exception {
|
public void demoJobHandler() throws Exception {
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
XxlJobLogger.log("beat at:" + i);
|
XxlJobHelper.log("beat at:" + i);
|
||||||
TimeUnit.SECONDS.sleep(2);
|
TimeUnit.SECONDS.sleep(2);
|
||||||
}
|
}
|
||||||
return ReturnT.SUCCESS;
|
// default success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,24 +50,23 @@ public class SampleXxlJob {
|
||||||
* 2、分片广播任务
|
* 2、分片广播任务
|
||||||
*/
|
*/
|
||||||
@XxlJob("shardingJobHandler")
|
@XxlJob("shardingJobHandler")
|
||||||
public ReturnT<String> shardingJobHandler(String param) throws Exception {
|
public void shardingJobHandler() throws Exception {
|
||||||
|
|
||||||
// 分片参数
|
// 分片参数
|
||||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
int shardIndex = XxlJobHelper.getShardIndex();
|
||||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
int shardTotal = XxlJobHelper.getShardTotal();
|
||||||
|
|
||||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||||
|
|
||||||
// 业务逻辑
|
// 业务逻辑
|
||||||
for (int i = 0; i < shardTotal; i++) {
|
for (int i = 0; i < shardTotal; i++) {
|
||||||
if (i == shardIndex) {
|
if (i == shardIndex) {
|
||||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
|
||||||
} else {
|
} else {
|
||||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
XxlJobHelper.log("第 {} 片, 忽略", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,28 +74,34 @@ public class SampleXxlJob {
|
||||||
* 3、命令行任务
|
* 3、命令行任务
|
||||||
*/
|
*/
|
||||||
@XxlJob("commandJobHandler")
|
@XxlJob("commandJobHandler")
|
||||||
public ReturnT<String> commandJobHandler(String param) throws Exception {
|
public void commandJobHandler() throws Exception {
|
||||||
String command = param;
|
String command = XxlJobHelper.getJobParam();
|
||||||
int exitValue = -1;
|
int exitValue = -1;
|
||||||
|
|
||||||
BufferedReader bufferedReader = null;
|
BufferedReader bufferedReader = null;
|
||||||
try {
|
try {
|
||||||
// command process
|
// command process
|
||||||
Process process = Runtime.getRuntime().exec(command);
|
ProcessBuilder processBuilder = new ProcessBuilder();
|
||||||
|
processBuilder.command(command);
|
||||||
|
processBuilder.redirectErrorStream(true);
|
||||||
|
|
||||||
|
Process process = processBuilder.start();
|
||||||
|
//Process process = Runtime.getRuntime().exec(command);
|
||||||
|
|
||||||
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
|
BufferedInputStream bufferedInputStream = new BufferedInputStream(process.getInputStream());
|
||||||
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
||||||
|
|
||||||
// command log
|
// command log
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
XxlJobLogger.log(line);
|
XxlJobHelper.log(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// command exit
|
// command exit
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
exitValue = process.exitValue();
|
exitValue = process.exitValue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (bufferedReader != null) {
|
if (bufferedReader != null) {
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
|
@ -106,10 +109,11 @@ public class SampleXxlJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitValue == 0) {
|
if (exitValue == 0) {
|
||||||
return IJobHandler.SUCCESS;
|
// default success
|
||||||
} else {
|
} else {
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
|
XxlJobHelper.handleFail("command exit value("+exitValue+") is failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -121,13 +125,17 @@ public class SampleXxlJob {
|
||||||
* "data: content\n";
|
* "data: content\n";
|
||||||
*/
|
*/
|
||||||
@XxlJob("httpJobHandler")
|
@XxlJob("httpJobHandler")
|
||||||
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
public void httpJobHandler() throws Exception {
|
||||||
|
|
||||||
// param parse
|
// param parse
|
||||||
|
String param = XxlJobHelper.getJobParam();
|
||||||
if (param==null || param.trim().length()==0) {
|
if (param==null || param.trim().length()==0) {
|
||||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
XxlJobHelper.log("param["+ param +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] httpParams = param.split("\n");
|
String[] httpParams = param.split("\n");
|
||||||
String url = null;
|
String url = null;
|
||||||
String method = null;
|
String method = null;
|
||||||
|
@ -146,12 +154,16 @@ public class SampleXxlJob {
|
||||||
|
|
||||||
// param valid
|
// param valid
|
||||||
if (url==null || url.trim().length()==0) {
|
if (url==null || url.trim().length()==0) {
|
||||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
XxlJobHelper.log("url["+ url +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
||||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
XxlJobHelper.log("method["+ method +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
boolean isPostMethod = method.equals("POST");
|
boolean isPostMethod = method.equals("POST");
|
||||||
|
|
||||||
|
@ -200,11 +212,14 @@ public class SampleXxlJob {
|
||||||
}
|
}
|
||||||
String responseMsg = result.toString();
|
String responseMsg = result.toString();
|
||||||
|
|
||||||
XxlJobLogger.log(responseMsg);
|
XxlJobHelper.log(responseMsg);
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (bufferedReader != null) {
|
if (bufferedReader != null) {
|
||||||
|
@ -214,7 +229,7 @@ public class SampleXxlJob {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
XxlJobLogger.log(e2);
|
XxlJobHelper.log(e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,9 +239,8 @@ public class SampleXxlJob {
|
||||||
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
||||||
*/
|
*/
|
||||||
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
||||||
public ReturnT<String> demoJobHandler2(String param) throws Exception {
|
public void demoJobHandler2() throws Exception {
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
public void init(){
|
public void init(){
|
||||||
logger.info("init");
|
logger.info("init");
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
package com.xxl.job.executor.service.jobhandler;
|
package com.xxl.job.executor.service.jobhandler;
|
||||||
|
|
||||||
import com.xxl.job.core.biz.model.ReturnT;
|
import com.xxl.job.core.context.XxlJobHelper;
|
||||||
import com.xxl.job.core.context.XxlJobContext;
|
|
||||||
import com.xxl.job.core.handler.IJobHandler;
|
|
||||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||||
import com.xxl.job.core.log.XxlJobLogger;
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -22,9 +19,10 @@ import java.util.concurrent.TimeUnit;
|
||||||
* XxlJob开发示例(Bean模式)
|
* XxlJob开发示例(Bean模式)
|
||||||
*
|
*
|
||||||
* 开发步骤:
|
* 开发步骤:
|
||||||
* 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"
|
* 1、任务开发:在Spring Bean实例中,开发Job方法;
|
||||||
* 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
||||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;
|
||||||
|
* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;
|
||||||
*
|
*
|
||||||
* @author xuxueli 2019-12-11 21:52:51
|
* @author xuxueli 2019-12-11 21:52:51
|
||||||
*/
|
*/
|
||||||
|
@ -37,14 +35,14 @@ public class SampleXxlJob {
|
||||||
* 1、简单任务示例(Bean模式)
|
* 1、简单任务示例(Bean模式)
|
||||||
*/
|
*/
|
||||||
@XxlJob("demoJobHandler")
|
@XxlJob("demoJobHandler")
|
||||||
public ReturnT<String> demoJobHandler(String param) throws Exception {
|
public void demoJobHandler() throws Exception {
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
XxlJobLogger.log("beat at:" + i);
|
XxlJobHelper.log("beat at:" + i);
|
||||||
TimeUnit.SECONDS.sleep(2);
|
TimeUnit.SECONDS.sleep(2);
|
||||||
}
|
}
|
||||||
return ReturnT.SUCCESS;
|
// default success
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,24 +50,23 @@ public class SampleXxlJob {
|
||||||
* 2、分片广播任务
|
* 2、分片广播任务
|
||||||
*/
|
*/
|
||||||
@XxlJob("shardingJobHandler")
|
@XxlJob("shardingJobHandler")
|
||||||
public ReturnT<String> shardingJobHandler(String param) throws Exception {
|
public void shardingJobHandler() throws Exception {
|
||||||
|
|
||||||
// 分片参数
|
// 分片参数
|
||||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
int shardIndex = XxlJobHelper.getShardIndex();
|
||||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
int shardTotal = XxlJobHelper.getShardTotal();
|
||||||
|
|
||||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||||
|
|
||||||
// 业务逻辑
|
// 业务逻辑
|
||||||
for (int i = 0; i < shardTotal; i++) {
|
for (int i = 0; i < shardTotal; i++) {
|
||||||
if (i == shardIndex) {
|
if (i == shardIndex) {
|
||||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
|
||||||
} else {
|
} else {
|
||||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
XxlJobHelper.log("第 {} 片, 忽略", i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,8 +74,8 @@ public class SampleXxlJob {
|
||||||
* 3、命令行任务
|
* 3、命令行任务
|
||||||
*/
|
*/
|
||||||
@XxlJob("commandJobHandler")
|
@XxlJob("commandJobHandler")
|
||||||
public ReturnT<String> commandJobHandler(String param) throws Exception {
|
public void commandJobHandler() throws Exception {
|
||||||
String command = param;
|
String command = XxlJobHelper.getJobParam();
|
||||||
int exitValue = -1;
|
int exitValue = -1;
|
||||||
|
|
||||||
BufferedReader bufferedReader = null;
|
BufferedReader bufferedReader = null;
|
||||||
|
@ -97,14 +94,14 @@ public class SampleXxlJob {
|
||||||
// command log
|
// command log
|
||||||
String line;
|
String line;
|
||||||
while ((line = bufferedReader.readLine()) != null) {
|
while ((line = bufferedReader.readLine()) != null) {
|
||||||
XxlJobLogger.log(line);
|
XxlJobHelper.log(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
// command exit
|
// command exit
|
||||||
process.waitFor();
|
process.waitFor();
|
||||||
exitValue = process.exitValue();
|
exitValue = process.exitValue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
} finally {
|
} finally {
|
||||||
if (bufferedReader != null) {
|
if (bufferedReader != null) {
|
||||||
bufferedReader.close();
|
bufferedReader.close();
|
||||||
|
@ -112,10 +109,11 @@ public class SampleXxlJob {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitValue == 0) {
|
if (exitValue == 0) {
|
||||||
return IJobHandler.SUCCESS;
|
// default success
|
||||||
} else {
|
} else {
|
||||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "command exit value("+exitValue+") is failed");
|
XxlJobHelper.handleFail("command exit value("+exitValue+") is failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -127,13 +125,17 @@ public class SampleXxlJob {
|
||||||
* "data: content\n";
|
* "data: content\n";
|
||||||
*/
|
*/
|
||||||
@XxlJob("httpJobHandler")
|
@XxlJob("httpJobHandler")
|
||||||
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
public void httpJobHandler() throws Exception {
|
||||||
|
|
||||||
// param parse
|
// param parse
|
||||||
|
String param = XxlJobHelper.getJobParam();
|
||||||
if (param==null || param.trim().length()==0) {
|
if (param==null || param.trim().length()==0) {
|
||||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
XxlJobHelper.log("param["+ param +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
String[] httpParams = param.split("\n");
|
String[] httpParams = param.split("\n");
|
||||||
String url = null;
|
String url = null;
|
||||||
String method = null;
|
String method = null;
|
||||||
|
@ -152,12 +154,16 @@ public class SampleXxlJob {
|
||||||
|
|
||||||
// param valid
|
// param valid
|
||||||
if (url==null || url.trim().length()==0) {
|
if (url==null || url.trim().length()==0) {
|
||||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
XxlJobHelper.log("url["+ url +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
||||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
XxlJobHelper.log("method["+ method +"] invalid.");
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
boolean isPostMethod = method.equals("POST");
|
boolean isPostMethod = method.equals("POST");
|
||||||
|
|
||||||
|
@ -206,11 +212,14 @@ public class SampleXxlJob {
|
||||||
}
|
}
|
||||||
String responseMsg = result.toString();
|
String responseMsg = result.toString();
|
||||||
|
|
||||||
XxlJobLogger.log(responseMsg);
|
XxlJobHelper.log(responseMsg);
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
|
return;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
XxlJobLogger.log(e);
|
XxlJobHelper.log(e);
|
||||||
return ReturnT.FAIL;
|
|
||||||
|
XxlJobHelper.handleFail();
|
||||||
|
return;
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (bufferedReader != null) {
|
if (bufferedReader != null) {
|
||||||
|
@ -220,7 +229,7 @@ public class SampleXxlJob {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
}
|
}
|
||||||
} catch (Exception e2) {
|
} catch (Exception e2) {
|
||||||
XxlJobLogger.log(e2);
|
XxlJobHelper.log(e2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,9 +239,8 @@ public class SampleXxlJob {
|
||||||
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
||||||
*/
|
*/
|
||||||
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
||||||
public ReturnT<String> demoJobHandler2(String param) throws Exception {
|
public void demoJobHandler2() throws Exception {
|
||||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||||
return ReturnT.SUCCESS;
|
|
||||||
}
|
}
|
||||||
public void init(){
|
public void init(){
|
||||||
logger.info("init");
|
logger.info("init");
|
||||||
|
|
Loading…
Reference in New Issue