- 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-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-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-jfinal:JFinal version,executors managed by JFinal;
|
||||
|
||||
### 2.3 Configure and delploy "Schedule Center"
|
||||
|
||||
|
|
|
@ -559,7 +559,6 @@ XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅
|
|||
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
|
||||
:xxl-job-executor-sample-spring:Spring版本,通过Spring容器管理执行器,比较通用;
|
||||
:xxl-job-executor-sample-frameless:无框架版本;
|
||||
:xxl-job-executor-sample-jfinal:JFinal版本,通过JFinal管理执行器;
|
||||
|
||||
|
||||
### 2.3 配置部署“调度中心”
|
||||
|
@ -714,7 +713,6 @@ public XxlJobSpringExecutor xxlJobExecutor() {
|
|||
|
||||
xxl-job-executor-sample-springboot:项目编译打包成springboot类型的可执行JAR包,命令启动即可;
|
||||
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方法,执行任务逻辑。
|
||||
|
||||
#### 5.5.5 任务日志
|
||||
XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 "XxlJobLogger.log" 打印执行日志,“调度中心”查看执行日志时将会加载对应的日志文件。
|
||||
XXL-JOB会为每次调度请求生成一个单独的日志文件,需要通过 "XxlJobHelper.log" 打印执行日志,“调度中心”查看执行日志时将会加载对应的日志文件。
|
||||
|
||||
(历史版本通过重写LOG4J的Appender实现,存在依赖限制,该方式在新版本已经被抛弃)
|
||||
|
||||
|
@ -2062,37 +2060,38 @@ data: post-data
|
|||
注意:XxlJobSpringExecutor组件个别字段调整:“appName” 调整为 “appname” ,升级时该组件时需要注意;
|
||||
|
||||
### 7.31 版本 v2.3.0 Release Notes[迭代中]
|
||||
- 1、新增调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
|
||||
- 2、新增触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 "固定间隔触发、固定延时触发(规划)" 两种新触发方式;
|
||||
- 3、Cron编辑器增强:Cron编辑器修改cron时可实时查看最近运行时间;
|
||||
- 4、Cron编辑器问题修复:修复小概率情况下cron单个字段修改时导致其他字段被重置问题;
|
||||
- 5、新增任务属性 "XxlJobContext" ,统一维护任务上下文信息,包括任务ID、分片参数等,方便运行时存取任务相关信息;
|
||||
- 6.1、废弃 "ShardingUtil" 组件:改用 "XxlJobContext.getXxlJobContext().getShardIndex()/getShardTotal();" 获取分片参数;
|
||||
- 6.2、日志组件逻辑调整:日志组件改为通过 XxlJobContext 获取任务上下文并匹配写入对应日志文件;
|
||||
- 6、执行器注册组件优化:注册逻辑调整为异步方式,提高注册性能;
|
||||
- 7、执行器鉴权校验:执行器启动时主动校验accessToken,为空则主动Warn告警;(已规划安全强化:AccessToken动态生成、动态启停等)
|
||||
- 8、邮箱告警配置优化:将"spring.mail.from"与"spring.mail.username"属性拆分开,更加灵活的支持一些无密码邮箱服务;
|
||||
- 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、[规划中]任务日志重构:一次调度只记录一条主任务,维护起止时间和状态。
|
||||
- 1、【新增】调度过期策略:调度中心错过调度时间的补偿处理策略,包括:忽略、立即补偿触发一次等;
|
||||
- 2、【新增】触发策略:除了常规Cron、API、父子任务触发方式外,新增提供 "固定间隔触发、(固定延时触发,实验中)" 新触发方式;
|
||||
- 3、【新增】新增任务辅助工具 "XxlJobHelper",提供统一任务辅助能力,包括:任务上下文信息维护获取(任务参数、任务ID、分片参数)、日志输出、任务结果设置……等;
|
||||
- 3.1、"ShardingUtil" 组件废弃:改用 "XxlJobHelper.getShardIndex()/getShardTotal();" 获取分片参数;
|
||||
- 3.2、"XxlJobLogger" 组件废弃:改用 "XxlJobHelper.log" 进行日志输出;
|
||||
- 4、【优化】任务核心类 "IJobHandler" 的 "execute" 方法取消出入参设计。改为通过 "XxlJobHelper.getJobParam" 获取任务参数并替代方法入参,通过 "XxlJobHelper.handleSuccess/handleFail" 设置任务结果并替代方法出参;
|
||||
- 4、【优化】Cron编辑器增强:Cron编辑器修改cron时可实时查看最近运行时间;
|
||||
- 5、【优化】执行器示例项目规范整理;
|
||||
- 6、【优化】任务调度生命周期重构:调度(schedule)、触发(trigger)、执行(handle)、回调(callback)、结束(complete);
|
||||
- 7、【优化】[规划中]任务日志重构:一次调度只记录一条主任务,维护起止时间和状态。
|
||||
- 普通任务:只记录一条主任务;
|
||||
- 广播任务:记录一条主任务,每个分片任务记录一条次任务,关联在主任务上;
|
||||
- 重试任务:失败时,新增主任务。所有调度记录,包括入口调度和重试调度,均挂载主任务上。
|
||||
- 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,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.util.I18nUtil;
|
||||
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.LoggerFactory;
|
||||
|
||||
|
@ -47,7 +47,7 @@ public class XxlJobCompleter {
|
|||
|
||||
// 1、handle success, to trigger child job
|
||||
String triggerChildMsg = null;
|
||||
if (IJobHandler.SUCCESS.getCode() == xxlJobLog.getHandleCode()) {
|
||||
if (XxlJobContext.HANDLE_COCE_SUCCESS == xxlJobLog.getHandleCode()) {
|
||||
XxlJobInfo xxlJobInfo = XxlJobAdminConfig.getAdminConfig().getXxlJobInfoDao().loadById(xxlJobLog.getJobId());
|
||||
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>";
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
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.conf.XxlJobAdminConfig;
|
||||
import com.xxl.job.admin.core.model.XxlJobLog;
|
||||
import com.xxl.job.admin.core.util.I18nUtil;
|
||||
import com.xxl.job.core.biz.model.HandleCallbackParam;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
import com.xxl.job.core.util.DateUtil;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -144,7 +143,7 @@ public class JobCompleteHelper {
|
|||
for (HandleCallbackParam handleCallbackParam: callbackParamList) {
|
||||
ReturnT<String> callbackResult = callback(handleCallbackParam);
|
||||
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) {
|
||||
handleMsg.append(log.getHandleMsg()).append("<br>");
|
||||
}
|
||||
if (handleCallbackParam.getExecuteResult().getMsg() != null) {
|
||||
handleMsg.append(handleCallbackParam.getExecuteResult().getMsg());
|
||||
if (handleCallbackParam.getHandleMsg() != null) {
|
||||
handleMsg.append(handleCallbackParam.getHandleMsg());
|
||||
}
|
||||
|
||||
// success, save log
|
||||
log.setHandleTime(new Date());
|
||||
log.setHandleCode(handleCallbackParam.getExecuteResult().getCode());
|
||||
log.setHandleCode(handleCallbackParam.getHandleCode());
|
||||
log.setHandleMsg(handleMsg.toString());
|
||||
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']").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');
|
||||
});
|
||||
var addModalValidate = $("#addModal .form").validate({
|
||||
|
|
|
@ -245,16 +245,14 @@
|
|||
<textarea class="glueSource_java" style="display:none;" >
|
||||
package com.xxl.job.service.handler;
|
||||
|
||||
import com.xxl.job.core.log.XxlJobLogger;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
|
||||
public class DemoGlueJobHandler extends IJobHandler {
|
||||
|
||||
@Override
|
||||
public ReturnT<String> execute(String param) throws Exception {
|
||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
||||
return ReturnT.SUCCESS;
|
||||
public void execute() throws Exception {
|
||||
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.RegistryParam;
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.context.XxlJobContext;
|
||||
import com.xxl.job.core.enums.RegistryConfig;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
@ -30,7 +31,7 @@ public class AdminBizTest {
|
|||
|
||||
HandleCallbackParam param = new HandleCallbackParam();
|
||||
param.setLogId(1);
|
||||
param.setExecuteResult(ReturnT.SUCCESS);
|
||||
param.setHandleCode(XxlJobContext.HANDLE_COCE_SUCCESS);
|
||||
|
||||
List<HandleCallbackParam> callbackParamList = Arrays.asList(param);
|
||||
|
||||
|
|
|
@ -11,13 +11,15 @@ public class HandleCallbackParam implements Serializable {
|
|||
private long logId;
|
||||
private long logDateTim;
|
||||
|
||||
private ReturnT<String> executeResult;
|
||||
private int handleCode;
|
||||
private String handleMsg;
|
||||
|
||||
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.logDateTim = logDateTim;
|
||||
this.executeResult = executeResult;
|
||||
this.handleCode = handleCode;
|
||||
this.handleMsg = handleMsg;
|
||||
}
|
||||
|
||||
public long getLogId() {
|
||||
|
@ -36,12 +38,20 @@ public class HandleCallbackParam implements Serializable {
|
|||
this.logDateTim = logDateTim;
|
||||
}
|
||||
|
||||
public ReturnT<String> getExecuteResult() {
|
||||
return executeResult;
|
||||
public int getHandleCode() {
|
||||
return handleCode;
|
||||
}
|
||||
|
||||
public void setExecuteResult(ReturnT<String> executeResult) {
|
||||
this.executeResult = executeResult;
|
||||
public void setHandleCode(int handleCode) {
|
||||
this.handleCode = handleCode;
|
||||
}
|
||||
|
||||
public String getHandleMsg() {
|
||||
return handleMsg;
|
||||
}
|
||||
|
||||
public void setHandleMsg(String handleMsg) {
|
||||
this.handleMsg = handleMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,7 +59,8 @@ public class HandleCallbackParam implements Serializable {
|
|||
return "HandleCallbackParam{" +
|
||||
"logId=" + logId +
|
||||
", logDateTim=" + logDateTim +
|
||||
", executeResult=" + executeResult +
|
||||
", handleCode=" + handleCode +
|
||||
", handleMsg='" + handleMsg + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
|
|
@ -8,16 +8,31 @@ package com.xxl.job.core.context;
|
|||
*/
|
||||
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
|
||||
*/
|
||||
private final long jobId;
|
||||
|
||||
/**
|
||||
* job param
|
||||
*/
|
||||
private final String jobParam;
|
||||
|
||||
// ---------------------- for log ----------------------
|
||||
|
||||
/**
|
||||
* job log filename
|
||||
*/
|
||||
private final String jobLogFileName;
|
||||
|
||||
// ---------------------- for shard ----------------------
|
||||
|
||||
/**
|
||||
* shard index
|
||||
*/
|
||||
|
@ -28,18 +43,42 @@ public class XxlJobContext {
|
|||
*/
|
||||
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.jobParam = jobParam;
|
||||
this.jobLogFileName = jobLogFileName;
|
||||
this.shardIndex = shardIndex;
|
||||
this.shardTotal = shardTotal;
|
||||
|
||||
this.handleCode = HANDLE_COCE_SUCCESS; // default success
|
||||
}
|
||||
|
||||
public long getJobId() {
|
||||
return jobId;
|
||||
}
|
||||
|
||||
public String getJobParam() {
|
||||
return jobParam;
|
||||
}
|
||||
|
||||
public String getJobLogFileName() {
|
||||
return jobLogFileName;
|
||||
}
|
||||
|
@ -52,6 +91,21 @@ public class XxlJobContext {
|
|||
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 ----------------------
|
||||
|
||||
|
|
|
@ -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 ----------------------
|
||||
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){
|
||||
logger.info(">>>>>>>>>>> xxl-job register jobhandler success, name:{}, jobHandler:{}", name, jobHandler);
|
||||
return jobHandlerRepository.put(name, jobHandler);
|
||||
}
|
||||
public static IJobHandler loadJobHandler(String name){
|
||||
return jobHandlerRepository.get(name);
|
||||
}
|
||||
|
||||
|
||||
// ---------------------- 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;
|
||||
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.core.glue.GlueFactory;
|
||||
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()) {
|
||||
Method method = methodXxlJobEntry.getKey();
|
||||
Method executeMethod = methodXxlJobEntry.getKey();
|
||||
XxlJob xxlJob = methodXxlJobEntry.getValue();
|
||||
if (xxlJob == null) {
|
||||
continue;
|
||||
|
@ -112,22 +111,23 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
|||
|
||||
String name = xxlJob.value();
|
||||
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) {
|
||||
throw new RuntimeException("xxl-job jobhandler[" + name + "] naming conflicts.");
|
||||
}
|
||||
|
||||
// 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() + "] , " +
|
||||
"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) \" .");
|
||||
}
|
||||
method.setAccessible(true);
|
||||
}*/
|
||||
|
||||
executeMethod.setAccessible(true);
|
||||
|
||||
// init and destory
|
||||
Method initMethod = null;
|
||||
|
@ -138,7 +138,7 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
|||
initMethod = bean.getClass().getDeclaredMethod(xxlJob.init());
|
||||
initMethod.setAccessible(true);
|
||||
} 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) {
|
||||
|
@ -146,12 +146,12 @@ public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationC
|
|||
destroyMethod = bean.getClass().getDeclaredMethod(xxlJob.destroy());
|
||||
destroyMethod.setAccessible(true);
|
||||
} 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
|
||||
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;
|
||||
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
/**
|
||||
* job handler
|
||||
*
|
||||
|
@ -12,28 +8,21 @@ import java.lang.reflect.InvocationTargetException;
|
|||
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
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
* @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
|
||||
*/
|
||||
public void init() throws InvocationTargetException, IllegalAccessException {
|
||||
public void init() throws Exception {
|
||||
// do something
|
||||
}
|
||||
|
||||
|
@ -41,7 +30,7 @@ public abstract class IJobHandler {
|
|||
/**
|
||||
* destroy handler, invoked when JobThread destroy
|
||||
*/
|
||||
public void destroy() throws InvocationTargetException, IllegalAccessException {
|
||||
public void destroy() throws Exception {
|
||||
// do something
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
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.log.XxlJobLogger;
|
||||
|
||||
/**
|
||||
* glue job handler
|
||||
|
@ -22,9 +21,9 @@ public class GlueJobHandler extends IJobHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ReturnT<String> execute(String param) throws Exception {
|
||||
XxlJobLogger.log("----------- glue.version:"+ glueUpdatetime +" -----------");
|
||||
return jobHandler.execute(param);
|
||||
public void execute() throws Exception {
|
||||
XxlJobHelper.log("----------- glue.version:"+ glueUpdatetime +" -----------");
|
||||
jobHandler.execute();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
package com.xxl.job.core.handler.impl;
|
||||
|
||||
import com.xxl.job.core.biz.model.ReturnT;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
|
@ -25,19 +23,19 @@ public class MethodJobHandler extends IJobHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ReturnT<String> execute(String param) throws Exception {
|
||||
return (ReturnT<String>) method.invoke(target, new Object[]{param});
|
||||
public void execute() throws Exception {
|
||||
method.invoke(target);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init() throws InvocationTargetException, IllegalAccessException {
|
||||
public void init() throws Exception {
|
||||
if(initMethod != null) {
|
||||
initMethod.invoke(target);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() throws InvocationTargetException, IllegalAccessException {
|
||||
public void destroy() throws Exception {
|
||||
if(destroyMethod != null) {
|
||||
destroyMethod.invoke(target);
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
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.XxlJobHelper;
|
||||
import com.xxl.job.core.glue.GlueTypeEnum;
|
||||
import com.xxl.job.core.handler.IJobHandler;
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
import com.xxl.job.core.log.XxlJobLogger;
|
||||
import com.xxl.job.core.util.ScriptUtil;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -46,10 +45,11 @@ public class ScriptJobHandler extends IJobHandler {
|
|||
}
|
||||
|
||||
@Override
|
||||
public ReturnT<String> execute(String param) throws Exception {
|
||||
public void execute() throws Exception {
|
||||
|
||||
if (!glueType.isScript()) {
|
||||
return new ReturnT<String>(IJobHandler.FAIL.getCode(), "glueType["+ glueType +"] invalid.");
|
||||
XxlJobHelper.handleFail("glueType["+ glueType +"] invalid.");
|
||||
return;
|
||||
}
|
||||
|
||||
// cmd
|
||||
|
@ -72,18 +72,20 @@ public class ScriptJobHandler extends IJobHandler {
|
|||
|
||||
// script params:0=param、1=分片序号、2=分片总数
|
||||
String[] scriptParams = new String[3];
|
||||
scriptParams[0] = param;
|
||||
scriptParams[0] = XxlJobHelper.getJobParam();
|
||||
scriptParams[1] = String.valueOf(XxlJobContext.getXxlJobContext().getShardIndex());
|
||||
scriptParams[2] = String.valueOf(XxlJobContext.getXxlJobContext().getShardTotal());
|
||||
|
||||
// invoke
|
||||
XxlJobLogger.log("----------- script file:"+ scriptFileName +" -----------");
|
||||
XxlJobHelper.log("----------- script file:"+ scriptFileName +" -----------");
|
||||
int exitValue = ScriptUtil.execToFile(cmd, scriptFileName, logFileName, scriptParams);
|
||||
|
||||
if (exitValue == 0) {
|
||||
return IJobHandler.SUCCESS;
|
||||
XxlJobHelper.handleSuccess();
|
||||
return;
|
||||
} 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.TriggerParam;
|
||||
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.handler.IJobHandler;
|
||||
import com.xxl.job.core.log.XxlJobFileAppender;
|
||||
import com.xxl.job.core.log.XxlJobLogger;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -106,7 +106,6 @@ public class JobThread extends Thread{
|
|||
idleTimes++;
|
||||
|
||||
TriggerParam triggerParam = null;
|
||||
ReturnT<String> executeResult = null;
|
||||
try {
|
||||
// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
|
||||
triggerParam = triggerQueue.poll(3L, TimeUnit.SECONDS);
|
||||
|
@ -117,54 +116,68 @@ public class JobThread extends Thread{
|
|||
|
||||
// log filename, like "logPath/yyyy-MM-dd/9999.log"
|
||||
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(triggerParam.getLogDateTime()), triggerParam.getLogId());
|
||||
XxlJobContext.setXxlJobContext(new XxlJobContext(
|
||||
XxlJobContext xxlJobContext = new XxlJobContext(
|
||||
triggerParam.getJobId(),
|
||||
triggerParam.getExecutorParams(),
|
||||
logFileName,
|
||||
triggerParam.getBroadcastIndex(),
|
||||
triggerParam.getBroadcastTotal()));
|
||||
triggerParam.getBroadcastTotal());
|
||||
|
||||
// init job context
|
||||
XxlJobContext.setXxlJobContext(xxlJobContext);
|
||||
|
||||
// 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) {
|
||||
// limit timeout
|
||||
Thread futureThread = null;
|
||||
try {
|
||||
final TriggerParam triggerParamTmp = triggerParam;
|
||||
FutureTask<ReturnT<String>> futureTask = new FutureTask<ReturnT<String>>(new Callable<ReturnT<String>>() {
|
||||
FutureTask<Boolean> futureTask = new FutureTask<Boolean>(new Callable<Boolean>() {
|
||||
@Override
|
||||
public ReturnT<String> call() throws Exception {
|
||||
return handler.execute(triggerParamTmp.getExecutorParams());
|
||||
public Boolean call() throws Exception {
|
||||
|
||||
// init job context
|
||||
XxlJobContext.setXxlJobContext(xxlJobContext);
|
||||
|
||||
handler.execute();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
futureThread = new Thread(futureTask);
|
||||
futureThread.start();
|
||||
|
||||
executeResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
|
||||
Boolean tempResult = futureTask.get(triggerParam.getExecutorTimeout(), TimeUnit.SECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
|
||||
XxlJobLogger.log("<br>----------- xxl-job job execute timeout");
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log("<br>----------- xxl-job job execute timeout");
|
||||
XxlJobHelper.log(e);
|
||||
|
||||
executeResult = new ReturnT<String>(IJobHandler.FAIL_TIMEOUT.getCode(), "job execute timeout ");
|
||||
// handle result
|
||||
XxlJobHelper.handleTimeout("job execute timeout ");
|
||||
} finally {
|
||||
futureThread.interrupt();
|
||||
}
|
||||
} else {
|
||||
// just execute
|
||||
executeResult = handler.execute(triggerParam.getExecutorParams());
|
||||
handler.execute();
|
||||
}
|
||||
|
||||
if (executeResult == null) {
|
||||
executeResult = IJobHandler.FAIL;
|
||||
// valid execute handle data
|
||||
if (XxlJobContext.getXxlJobContext().getHandleCode() <= 0) {
|
||||
XxlJobHelper.handleFail("job handle result lost.");
|
||||
} else {
|
||||
executeResult.setMsg(
|
||||
(executeResult!=null&&executeResult.getMsg()!=null&&executeResult.getMsg().length()>50000)
|
||||
?executeResult.getMsg().substring(0, 50000).concat("...")
|
||||
:executeResult.getMsg());
|
||||
executeResult.setContent(null); // limit obj size
|
||||
String tempHandleMsg = XxlJobContext.getXxlJobContext().getHandleMsg();
|
||||
tempHandleMsg = (tempHandleMsg!=null&&tempHandleMsg.length()>50000)
|
||||
?tempHandleMsg.substring(0, 50000).concat("...")
|
||||
:tempHandleMsg;
|
||||
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 {
|
||||
if (idleTimes > 30) {
|
||||
|
@ -175,25 +188,36 @@ public class JobThread extends Thread{
|
|||
}
|
||||
} catch (Throwable e) {
|
||||
if (toStop) {
|
||||
XxlJobLogger.log("<br>----------- JobThread toStop, stopReason:" + stopReason);
|
||||
XxlJobHelper.log("<br>----------- JobThread toStop, stopReason:" + stopReason);
|
||||
}
|
||||
|
||||
// handle result
|
||||
StringWriter stringWriter = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(stringWriter));
|
||||
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 {
|
||||
if(triggerParam != null) {
|
||||
// callback handler info
|
||||
if (!toStop) {
|
||||
// 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 {
|
||||
// is killed
|
||||
ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [job running, killed]");
|
||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTime(), stopResult));
|
||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(
|
||||
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();
|
||||
if (triggerParam!=null) {
|
||||
// is killed
|
||||
ReturnT<String> stopResult = new ReturnT<String>(ReturnT.FAIL_CODE, stopReason + " [job not executed, in the job queue, killed.]");
|
||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(triggerParam.getLogId(), triggerParam.getLogDateTime(), stopResult));
|
||||
TriggerCallbackThread.pushCallBack(new HandleCallbackParam(
|
||||
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.ReturnT;
|
||||
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.executor.XxlJobExecutor;
|
||||
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.JdkSerializeTool;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -190,10 +190,11 @@ public class TriggerCallbackThread {
|
|||
String logFileName = XxlJobFileAppender.makeLogFileName(new Date(callbackParam.getLogDateTim()), callbackParam.getLogId());
|
||||
XxlJobContext.setXxlJobContext(new XxlJobContext(
|
||||
-1,
|
||||
null,
|
||||
logFileName,
|
||||
-1,
|
||||
-1));
|
||||
XxlJobLogger.log(logContent);
|
||||
XxlJobHelper.log(logContent);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
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.IOException;
|
||||
|
@ -83,7 +83,7 @@ public class ScriptUtil {
|
|||
try {
|
||||
copy(process.getInputStream(), finalFileOutputStream, new byte[1024]);
|
||||
} catch (IOException e) {
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -93,7 +93,7 @@ public class ScriptUtil {
|
|||
try {
|
||||
copy(process.getErrorStream(), finalFileOutputStream, new byte[1024]);
|
||||
} catch (IOException e) {
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log(e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -109,14 +109,14 @@ public class ScriptUtil {
|
|||
|
||||
return exitValue;
|
||||
} catch (Exception e) {
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log(e);
|
||||
return -1;
|
||||
} finally {
|
||||
if (fileOutputStream != null) {
|
||||
try {
|
||||
fileOutputStream.close();
|
||||
} 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-springboot</module>
|
||||
<module>xxl-job-executor-sample-spring</module>
|
||||
<module>xxl-job-executor-sample-jfinal</module>
|
||||
</modules>
|
||||
|
||||
</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.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.xuxueli.executor.sample.frameless.jobhandler.DemoJobHandler;
|
||||
import com.xuxueli.executor.sample.frameless.jobhandler.HttpJobHandler;
|
||||
import com.xuxueli.executor.sample.frameless.jobhandler.ShardingJobHandler;
|
||||
import com.xxl.job.core.executor.XxlJobExecutor;
|
||||
import com.xxl.job.executor.sample.frameless.jobhandler.SampleXxlJob;
|
||||
import com.xxl.job.core.executor.impl.XxlJobSimpleExecutor;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.Properties;
|
||||
|
||||
/**
|
||||
|
@ -25,25 +23,18 @@ public class FrameLessXxlJobConfig {
|
|||
}
|
||||
|
||||
|
||||
private XxlJobExecutor xxlJobExecutor = null;
|
||||
private XxlJobSimpleExecutor xxlJobExecutor = null;
|
||||
|
||||
/**
|
||||
* init
|
||||
*/
|
||||
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
|
||||
Properties xxlJobProp = loadProperties("xxl-job-executor.properties");
|
||||
|
||||
|
||||
// init executor
|
||||
xxlJobExecutor = new XxlJobExecutor();
|
||||
xxlJobExecutor = new XxlJobSimpleExecutor();
|
||||
xxlJobExecutor.setAdminAddresses(xxlJobProp.getProperty("xxl.job.admin.addresses"));
|
||||
xxlJobExecutor.setAccessToken(xxlJobProp.getProperty("xxl.job.accessToken"));
|
||||
xxlJobExecutor.setAppname(xxlJobProp.getProperty("xxl.job.executor.appname"));
|
||||
|
@ -53,6 +44,9 @@ public class FrameLessXxlJobConfig {
|
|||
xxlJobExecutor.setLogPath(xxlJobProp.getProperty("xxl.job.executor.logpath"));
|
||||
xxlJobExecutor.setLogRetentionDays(Integer.valueOf(xxlJobProp.getProperty("xxl.job.executor.logretentiondays")));
|
||||
|
||||
// registry job bean
|
||||
xxlJobExecutor.setXxlJobBeanList(Arrays.asList(new SampleXxlJob()));
|
||||
|
||||
// start executor
|
||||
try {
|
||||
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 server-info
|
||||
xxl.job.executor.ip=
|
||||
xxl.job.executor.port=9999
|
||||
xxl.job.executor.port=9998
|
||||
### xxl-job executor log-path
|
||||
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
|
||||
### 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;
|
||||
|
||||
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.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import com.xxl.job.core.log.XxlJobLogger;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -22,9 +19,10 @@ import java.util.concurrent.TimeUnit;
|
|||
* XxlJob开发示例(Bean模式)
|
||||
*
|
||||
* 开发步骤:
|
||||
* 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"
|
||||
* 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
||||
* 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
|
||||
*/
|
||||
|
@ -37,14 +35,14 @@ public class SampleXxlJob {
|
|||
* 1、简单任务示例(Bean模式)
|
||||
*/
|
||||
@XxlJob("demoJobHandler")
|
||||
public ReturnT<String> demoJobHandler(String param) throws Exception {
|
||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
||||
public void demoJobHandler() throws Exception {
|
||||
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
XxlJobLogger.log("beat at:" + i);
|
||||
XxlJobHelper.log("beat at:" + i);
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
// default success
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,24 +50,23 @@ public class SampleXxlJob {
|
|||
* 2、分片广播任务
|
||||
*/
|
||||
@XxlJob("shardingJobHandler")
|
||||
public ReturnT<String> shardingJobHandler(String param) throws Exception {
|
||||
public void shardingJobHandler() throws Exception {
|
||||
|
||||
// 分片参数
|
||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
||||
int shardIndex = XxlJobHelper.getShardIndex();
|
||||
int shardTotal = XxlJobHelper.getShardTotal();
|
||||
|
||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||
XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||
|
||||
// 业务逻辑
|
||||
for (int i = 0; i < shardTotal; i++) {
|
||||
if (i == shardIndex) {
|
||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
||||
XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
|
||||
} else {
|
||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
||||
XxlJobHelper.log("第 {} 片, 忽略", i);
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,28 +74,34 @@ public class SampleXxlJob {
|
|||
* 3、命令行任务
|
||||
*/
|
||||
@XxlJob("commandJobHandler")
|
||||
public ReturnT<String> commandJobHandler(String param) throws Exception {
|
||||
String command = param;
|
||||
public void commandJobHandler() throws Exception {
|
||||
String command = XxlJobHelper.getJobParam();
|
||||
int exitValue = -1;
|
||||
|
||||
BufferedReader bufferedReader = null;
|
||||
try {
|
||||
// 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());
|
||||
bufferedReader = new BufferedReader(new InputStreamReader(bufferedInputStream));
|
||||
|
||||
// command log
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
XxlJobLogger.log(line);
|
||||
XxlJobHelper.log(line);
|
||||
}
|
||||
|
||||
// command exit
|
||||
process.waitFor();
|
||||
exitValue = process.exitValue();
|
||||
} catch (Exception e) {
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log(e);
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
bufferedReader.close();
|
||||
|
@ -106,10 +109,11 @@ public class SampleXxlJob {
|
|||
}
|
||||
|
||||
if (exitValue == 0) {
|
||||
return IJobHandler.SUCCESS;
|
||||
// default success
|
||||
} 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";
|
||||
*/
|
||||
@XxlJob("httpJobHandler")
|
||||
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
||||
public void httpJobHandler() throws Exception {
|
||||
|
||||
// param parse
|
||||
String param = XxlJobHelper.getJobParam();
|
||||
if (param==null || param.trim().length()==0) {
|
||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("param["+ param +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] httpParams = param.split("\n");
|
||||
String url = null;
|
||||
String method = null;
|
||||
|
@ -146,12 +154,16 @@ public class SampleXxlJob {
|
|||
|
||||
// param valid
|
||||
if (url==null || url.trim().length()==0) {
|
||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("url["+ url +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("method["+ method +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
boolean isPostMethod = method.equals("POST");
|
||||
|
||||
|
@ -200,11 +212,14 @@ public class SampleXxlJob {
|
|||
}
|
||||
String responseMsg = result.toString();
|
||||
|
||||
XxlJobLogger.log(responseMsg);
|
||||
return ReturnT.SUCCESS;
|
||||
XxlJobHelper.log(responseMsg);
|
||||
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
XxlJobLogger.log(e);
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log(e);
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
} finally {
|
||||
try {
|
||||
if (bufferedReader != null) {
|
||||
|
@ -214,7 +229,7 @@ public class SampleXxlJob {
|
|||
connection.disconnect();
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
XxlJobLogger.log(e2);
|
||||
XxlJobHelper.log(e2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -224,9 +239,8 @@ public class SampleXxlJob {
|
|||
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
||||
*/
|
||||
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
||||
public ReturnT<String> demoJobHandler2(String param) throws Exception {
|
||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
||||
return ReturnT.SUCCESS;
|
||||
public void demoJobHandler2() throws Exception {
|
||||
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||
}
|
||||
public void init(){
|
||||
logger.info("init");
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
package com.xxl.job.executor.service.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.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import com.xxl.job.core.log.XxlJobLogger;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
@ -22,9 +19,10 @@ import java.util.concurrent.TimeUnit;
|
|||
* XxlJob开发示例(Bean模式)
|
||||
*
|
||||
* 开发步骤:
|
||||
* 1、在Spring Bean实例中,开发Job方法,方式格式要求为 "public ReturnT<String> execute(String param)"
|
||||
* 2、为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
|
||||
* 3、执行日志:需要通过 "XxlJobLogger.log" 打印执行日志;
|
||||
* 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
|
||||
*/
|
||||
|
@ -37,14 +35,14 @@ public class SampleXxlJob {
|
|||
* 1、简单任务示例(Bean模式)
|
||||
*/
|
||||
@XxlJob("demoJobHandler")
|
||||
public ReturnT<String> demoJobHandler(String param) throws Exception {
|
||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
||||
public void demoJobHandler() throws Exception {
|
||||
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||
|
||||
for (int i = 0; i < 5; i++) {
|
||||
XxlJobLogger.log("beat at:" + i);
|
||||
XxlJobHelper.log("beat at:" + i);
|
||||
TimeUnit.SECONDS.sleep(2);
|
||||
}
|
||||
return ReturnT.SUCCESS;
|
||||
// default success
|
||||
}
|
||||
|
||||
|
||||
|
@ -52,24 +50,23 @@ public class SampleXxlJob {
|
|||
* 2、分片广播任务
|
||||
*/
|
||||
@XxlJob("shardingJobHandler")
|
||||
public ReturnT<String> shardingJobHandler(String param) throws Exception {
|
||||
public void shardingJobHandler() throws Exception {
|
||||
|
||||
// 分片参数
|
||||
int shardIndex = XxlJobContext.getXxlJobContext().getShardIndex();
|
||||
int shardTotal = XxlJobContext.getXxlJobContext().getShardTotal();
|
||||
int shardIndex = XxlJobHelper.getShardIndex();
|
||||
int shardTotal = XxlJobHelper.getShardTotal();
|
||||
|
||||
XxlJobLogger.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||
XxlJobHelper.log("分片参数:当前分片序号 = {}, 总分片数 = {}", shardIndex, shardTotal);
|
||||
|
||||
// 业务逻辑
|
||||
for (int i = 0; i < shardTotal; i++) {
|
||||
if (i == shardIndex) {
|
||||
XxlJobLogger.log("第 {} 片, 命中分片开始处理", i);
|
||||
XxlJobHelper.log("第 {} 片, 命中分片开始处理", i);
|
||||
} else {
|
||||
XxlJobLogger.log("第 {} 片, 忽略", i);
|
||||
XxlJobHelper.log("第 {} 片, 忽略", i);
|
||||
}
|
||||
}
|
||||
|
||||
return ReturnT.SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,8 +74,8 @@ public class SampleXxlJob {
|
|||
* 3、命令行任务
|
||||
*/
|
||||
@XxlJob("commandJobHandler")
|
||||
public ReturnT<String> commandJobHandler(String param) throws Exception {
|
||||
String command = param;
|
||||
public void commandJobHandler() throws Exception {
|
||||
String command = XxlJobHelper.getJobParam();
|
||||
int exitValue = -1;
|
||||
|
||||
BufferedReader bufferedReader = null;
|
||||
|
@ -97,14 +94,14 @@ public class SampleXxlJob {
|
|||
// command log
|
||||
String line;
|
||||
while ((line = bufferedReader.readLine()) != null) {
|
||||
XxlJobLogger.log(line);
|
||||
XxlJobHelper.log(line);
|
||||
}
|
||||
|
||||
// command exit
|
||||
process.waitFor();
|
||||
exitValue = process.exitValue();
|
||||
} catch (Exception e) {
|
||||
XxlJobLogger.log(e);
|
||||
XxlJobHelper.log(e);
|
||||
} finally {
|
||||
if (bufferedReader != null) {
|
||||
bufferedReader.close();
|
||||
|
@ -112,10 +109,11 @@ public class SampleXxlJob {
|
|||
}
|
||||
|
||||
if (exitValue == 0) {
|
||||
return IJobHandler.SUCCESS;
|
||||
// default success
|
||||
} 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";
|
||||
*/
|
||||
@XxlJob("httpJobHandler")
|
||||
public ReturnT<String> httpJobHandler(String param) throws Exception {
|
||||
public void httpJobHandler() throws Exception {
|
||||
|
||||
// param parse
|
||||
String param = XxlJobHelper.getJobParam();
|
||||
if (param==null || param.trim().length()==0) {
|
||||
XxlJobLogger.log("param["+ param +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("param["+ param +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
|
||||
String[] httpParams = param.split("\n");
|
||||
String url = null;
|
||||
String method = null;
|
||||
|
@ -152,12 +154,16 @@ public class SampleXxlJob {
|
|||
|
||||
// param valid
|
||||
if (url==null || url.trim().length()==0) {
|
||||
XxlJobLogger.log("url["+ url +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("url["+ url +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
if (method==null || !Arrays.asList("GET", "POST").contains(method)) {
|
||||
XxlJobLogger.log("method["+ method +"] invalid.");
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log("method["+ method +"] invalid.");
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
}
|
||||
boolean isPostMethod = method.equals("POST");
|
||||
|
||||
|
@ -206,11 +212,14 @@ public class SampleXxlJob {
|
|||
}
|
||||
String responseMsg = result.toString();
|
||||
|
||||
XxlJobLogger.log(responseMsg);
|
||||
return ReturnT.SUCCESS;
|
||||
XxlJobHelper.log(responseMsg);
|
||||
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
XxlJobLogger.log(e);
|
||||
return ReturnT.FAIL;
|
||||
XxlJobHelper.log(e);
|
||||
|
||||
XxlJobHelper.handleFail();
|
||||
return;
|
||||
} finally {
|
||||
try {
|
||||
if (bufferedReader != null) {
|
||||
|
@ -220,7 +229,7 @@ public class SampleXxlJob {
|
|||
connection.disconnect();
|
||||
}
|
||||
} catch (Exception e2) {
|
||||
XxlJobLogger.log(e2);
|
||||
XxlJobHelper.log(e2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,9 +239,8 @@ public class SampleXxlJob {
|
|||
* 5、生命周期任务示例:任务初始化与销毁时,支持自定义相关逻辑;
|
||||
*/
|
||||
@XxlJob(value = "demoJobHandler2", init = "init", destroy = "destroy")
|
||||
public ReturnT<String> demoJobHandler2(String param) throws Exception {
|
||||
XxlJobLogger.log("XXL-JOB, Hello World.");
|
||||
return ReturnT.SUCCESS;
|
||||
public void demoJobHandler2() throws Exception {
|
||||
XxlJobHelper.log("XXL-JOB, Hello World.");
|
||||
}
|
||||
public void init(){
|
||||
logger.info("init");
|
||||
|
|
Loading…
Reference in New Issue