添加任务超时属性,超时后失败

pull/MERGE
chuan 7 years ago
parent 4bc09cea16
commit 86acbcd777

@ -158,6 +158,7 @@ CREATE TABLE `XXL_JOB_QRTZ_TRIGGER_INFO` (
`update_time` datetime DEFAULT NULL, `update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者', `author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件', `alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`execute_timeout` int(11) NOT NULL DEFAULT 0 COMMENT '任务执行超时时间',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略', `executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler', `executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数', `executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',

@ -36,6 +36,17 @@ public class XxlJobInfo {
// copy from quartz // copy from quartz
private String jobStatus; // 任务状态 【base on quartz】 private String jobStatus; // 任务状态 【base on quartz】
private int executeTimeout; // 任务最多执行时间,超时后报警
public int getExecuteTimeout() {
return executeTimeout;
}
public void setExecuteTimeout(int executeTimeout) {
this.executeTimeout = executeTimeout;
}
public int getId() { public int getId() {
return id; return id;
} }

@ -63,6 +63,7 @@ public class JobFailMonitorHelper {
logger.info(">>>>>>>>>>> job monitor, job success, JobLogId:{}", jobLogId); logger.info(">>>>>>>>>>> job monitor, job success, JobLogId:{}", jobLogId);
} else if (IJobHandler.FAIL.getCode() == log.getTriggerCode() } else if (IJobHandler.FAIL.getCode() == log.getTriggerCode()
|| IJobHandler.FAIL.getCode() == log.getHandleCode() || IJobHandler.FAIL.getCode() == log.getHandleCode()
|| IJobHandler.TIMEOUT.getCode() == log.getHandleCode()
|| IJobHandler.FAIL_RETRY.getCode() == log.getHandleCode() ) { || IJobHandler.FAIL_RETRY.getCode() == log.getHandleCode() ) {
// job fail, // job fail,
failAlarm(log); failAlarm(log);

@ -96,6 +96,8 @@ public class XxlJobTrigger {
triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime()); triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
triggerParam.setBroadcastIndex(i); triggerParam.setBroadcastIndex(i);
triggerParam.setBroadcastTotal(addressList.size()); // update02 triggerParam.setBroadcastTotal(addressList.size()); // update02
// 执行超时时间
triggerParam.setExecuteTimeout(jobInfo.getExecuteTimeout());
// 4.2、trigger-run (route run / trigger remote executor) // 4.2、trigger-run (route run / trigger remote executor)
triggerResult = runExecutor(triggerParam, address); // update03 triggerResult = runExecutor(triggerParam, address); // update03
@ -164,6 +166,7 @@ public class XxlJobTrigger {
triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime()); triggerParam.setGlueUpdatetime(jobInfo.getGlueUpdatetime().getTime());
triggerParam.setBroadcastIndex(0); triggerParam.setBroadcastIndex(0);
triggerParam.setBroadcastTotal(1); triggerParam.setBroadcastTotal(1);
triggerParam.setExecuteTimeout(jobInfo.getExecuteTimeout());
// 4.2、trigger-run (route run / trigger remote executor) // 4.2、trigger-run (route run / trigger remote executor)
triggerResult = executorRouteStrategyEnum.getRouter().routeRun(triggerParam, addressList); triggerResult = executorRouteStrategyEnum.getRouter().routeRun(triggerParam, addressList);

@ -107,6 +107,7 @@ jobinfo_field_gluetype=运行模式
jobinfo_field_executorparam=任务参数 jobinfo_field_executorparam=任务参数
jobinfo_field_cron_unvalid=Cron格式非法 jobinfo_field_cron_unvalid=Cron格式非法
jobinfo_field_author=负责人 jobinfo_field_author=负责人
jobinfo_field_timeout=最大执行时间
jobinfo_field_alarmemail=报警邮件 jobinfo_field_alarmemail=报警邮件
jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔 jobinfo_field_alarmemail_placeholder=请输入报警邮件,多个邮件地址则逗号分隔
jobinfo_field_executorRouteStrategy=路由策略 jobinfo_field_executorRouteStrategy=路由策略
@ -157,6 +158,7 @@ joblog_clean_type_9=清理所有日志数据
joblog_clean_type_unvalid=清理类型参数异常 joblog_clean_type_unvalid=清理类型参数异常
joblog_handleCode_200=成功 joblog_handleCode_200=成功
joblog_handleCode_500=失败 joblog_handleCode_500=失败
joblog_handleCode_400=超时
joblog_handleCode_501=失败重试 joblog_handleCode_501=失败重试
joblog_kill_log=终止任务 joblog_kill_log=终止任务
joblog_kill_log_limit=调度失败,无法终止日志 joblog_kill_log_limit=调度失败,无法终止日志

@ -103,6 +103,7 @@ jobinfo_field_update=Edit Job
jobinfo_field_id=Job ID jobinfo_field_id=Job ID
jobinfo_field_jobgroup=Executor jobinfo_field_jobgroup=Executor
jobinfo_field_jobdesc=Job description jobinfo_field_jobdesc=Job description
jobinfo_field_timeout=Max execute time
jobinfo_field_gluetype=GLUE Type jobinfo_field_gluetype=GLUE Type
jobinfo_field_executorparam=Param jobinfo_field_executorparam=Param
jobinfo_field_cron_unvalid=The Cron is illegal jobinfo_field_cron_unvalid=The Cron is illegal
@ -157,6 +158,7 @@ joblog_clean_type_9=Clean up all log data
joblog_clean_type_unvalid=Clean type is illegal joblog_clean_type_unvalid=Clean type is illegal
joblog_handleCode_200=Success joblog_handleCode_200=Success
joblog_handleCode_500=Fail joblog_handleCode_500=Fail
joblog_handleCode_400=Timeout
joblog_handleCode_501=Fail retry joblog_handleCode_501=Fail retry
joblog_kill_log=Kill Job joblog_kill_log=Kill Job
joblog_kill_log_limit=Trigger Fail, can not kill job joblog_kill_log_limit=Trigger Fail, can not kill job

@ -26,6 +26,7 @@
<result column="glue_source" property="glueSource" /> <result column="glue_source" property="glueSource" />
<result column="glue_remark" property="glueRemark" /> <result column="glue_remark" property="glueRemark" />
<result column="glue_updatetime" property="glueUpdatetime" /> <result column="glue_updatetime" property="glueUpdatetime" />
<result column="execute_timeout" property="executeTimeout" />
<result column="child_jobid" property="childJobId" /> <result column="child_jobid" property="childJobId" />
</resultMap> </resultMap>
@ -48,6 +49,7 @@
t.glue_source, t.glue_source,
t.glue_remark, t.glue_remark,
t.glue_updatetime, t.glue_updatetime,
t.execute_timeout,
t.child_jobid t.child_jobid
</sql> </sql>
@ -103,7 +105,8 @@
glue_source, glue_source,
glue_remark, glue_remark,
glue_updatetime, glue_updatetime,
child_jobid child_jobid,
execute_timeout
) VALUES ( ) VALUES (
#{jobGroup}, #{jobGroup},
#{jobCron}, #{jobCron},
@ -121,7 +124,8 @@
#{glueSource}, #{glueSource},
#{glueRemark}, #{glueRemark},
NOW(), NOW(),
#{childJobId} #{childJobId},
#{executeTimeout}
); );
<!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id"> <!--<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID() SELECT LAST_INSERT_ID()
@ -152,7 +156,8 @@
glue_source = #{glueSource}, glue_source = #{glueSource},
glue_remark = #{glueRemark}, glue_remark = #{glueRemark},
glue_updatetime = #{glueUpdatetime}, glue_updatetime = #{glueUpdatetime},
child_jobid = #{childJobId} child_jobid = #{childJobId},
execute_timeout = ${executeTimeout}
WHERE id = #{id} WHERE id = #{id}
</update> </update>

@ -169,6 +169,11 @@
<div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div> <div class="col-sm-4"><input type="text" class="form-control" name="alarmEmail" placeholder="${I18n.jobinfo_field_alarmemail_placeholder}" maxlength="100" ></div>
</div> </div>
<div class="form-group">
<label for="lastname" class="col-sm-2 control-label">${I18n.jobinfo_field_timeout}<font color="red">*</font></label>
<div class="col-sm-4"><input type="text" class="form-control" name="executeTimeout" placeholder="0" maxlength="100" ></div>
</div>
<hr> <hr>
<div class="form-group"> <div class="form-group">
<div class="col-sm-offset-3 col-sm-6"> <div class="col-sm-offset-3 col-sm-6">

@ -362,6 +362,7 @@ $(function() {
$("#updateModal .form input[name='jobCron']").val( row.jobCron ); $("#updateModal .form input[name='jobCron']").val( row.jobCron );
$("#updateModal .form input[name='author']").val( row.author ); $("#updateModal .form input[name='author']").val( row.author );
$("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail ); $("#updateModal .form input[name='alarmEmail']").val( row.alarmEmail );
$("#updateModal .form input[name='executeTimeout']").val( row.executeTimeout );
$('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true); $('#updateModal .form select[name=executorRouteStrategy] option[value='+ row.executorRouteStrategy +']').prop('selected', true);
$("#updateModal .form input[name='executorHandler']").val( row.executorHandler ); $("#updateModal .form input[name='executorHandler']").val( row.executorHandler );
$("#updateModal .form input[name='executorParam']").val( row.executorParam ); $("#updateModal .form input[name='executorParam']").val( row.executorParam );

@ -159,6 +159,8 @@ $(function() {
html = '<span style="color: red">'+ I18n.joblog_handleCode_500 +'</span>'; html = '<span style="color: red">'+ I18n.joblog_handleCode_500 +'</span>';
} else if (data == 501) { } else if (data == 501) {
html = '<span style="color: red">'+ I18n.joblog_handleCode_501 +'</span>'; html = '<span style="color: red">'+ I18n.joblog_handleCode_501 +'</span>';
} else if (data == 400) {
html = '<span style="color: red">'+ I18n.joblog_handleCode_400 +'</span>';
} else if (data == 0) { } else if (data == 0) {
html = ''; html = '';
} }

@ -12,8 +12,11 @@ public class ReturnT<T> implements Serializable {
public static final int SUCCESS_CODE = 200; public static final int SUCCESS_CODE = 200;
public static final int FAIL_CODE = 500; public static final int FAIL_CODE = 500;
public static final int EXECUTE_TIMEOUT = 400;
public static final ReturnT<String> SUCCESS = new ReturnT<String>(null); public static final ReturnT<String> SUCCESS = new ReturnT<String>(null);
public static final ReturnT<String> FAIL = new ReturnT<String>(FAIL_CODE, null); public static final ReturnT<String> FAIL = new ReturnT<String>(FAIL_CODE, null);
public static final ReturnT<String> TIMEOUT = new ReturnT<String>(EXECUTE_TIMEOUT, "执行超时");
private int code; private int code;
private String msg; private String msg;

@ -24,6 +24,16 @@ public class TriggerParam implements Serializable{
private int broadcastIndex; private int broadcastIndex;
private int broadcastTotal; private int broadcastTotal;
private int executeTimeout;
public int getExecuteTimeout() {
return executeTimeout;
}
public void setExecuteTimeout(int executeTimeout) {
this.executeTimeout = executeTimeout;
}
public int getJobId() { public int getJobId() {
return jobId; return jobId;
} }

@ -14,6 +14,8 @@ public abstract class IJobHandler {
public static final ReturnT<String> SUCCESS = new ReturnT<String>(200, null); public static final ReturnT<String> SUCCESS = new ReturnT<String>(200, null);
/** fail */ /** fail */
public static final ReturnT<String> FAIL = new ReturnT<String>(500, null); public static final ReturnT<String> FAIL = new ReturnT<String>(500, null);
/** timeout */
public static final ReturnT<String> TIMEOUT = new ReturnT<String>(400, null);
/** fail retry */ /** fail retry */
public static final ReturnT<String> FAIL_RETRY = new ReturnT<String>(501, null); public static final ReturnT<String> FAIL_RETRY = new ReturnT<String>(501, null);

@ -16,8 +16,7 @@ import java.io.PrintWriter;
import java.io.StringWriter; import java.io.StringWriter;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.*;
import java.util.concurrent.TimeUnit;
/** /**
* handler thread * handler thread
@ -106,6 +105,7 @@ public class JobThread extends Thread{
TriggerParam triggerParam = null; TriggerParam triggerParam = null;
ReturnT<String> executeResult = null; ReturnT<String> executeResult = null;
ExecutorService singleThread = Executors.newSingleThreadExecutor();
try { try {
// to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout) // to check toStop signal, we need cycle, so wo cannot use queue.take(), instand of poll(timeout)
triggerParam = triggerQueue.poll(3L, TimeUnit.SECONDS); triggerParam = triggerQueue.poll(3L, TimeUnit.SECONDS);
@ -121,7 +121,27 @@ public class JobThread extends Thread{
// execute // execute
XxlJobLogger.log("<br>----------- xxl-job job execute start -----------<br>----------- Param:" + triggerParam.getExecutorParams()); XxlJobLogger.log("<br>----------- xxl-job job execute start -----------<br>----------- Param:" + triggerParam.getExecutorParams());
executeResult = handler.execute(triggerParam.getExecutorParams()); int executeTimeout = triggerParam.getExecuteTimeout();
final TriggerParam finalTriggerParam = triggerParam;
Future<ReturnT<String>> future = singleThread.submit(new Callable<ReturnT<String>>() {
@Override
public ReturnT<String> call() throws Exception {
return handler.execute(finalTriggerParam.getExecutorParams());
}
});
try {
if (executeTimeout > 0) {
executeResult = future.get(executeTimeout, TimeUnit.SECONDS);
} else {
executeResult = future.get();
}
} catch (TimeoutException timeoutException) {
executeResult = ReturnT.TIMEOUT;
}
if (executeResult == null) { if (executeResult == null) {
executeResult = IJobHandler.FAIL; executeResult = IJobHandler.FAIL;
} }
@ -144,6 +164,9 @@ public class JobThread extends Thread{
XxlJobLogger.log("<br>----------- JobThread Exception:" + errorMsg + "<br>----------- xxl-job job execute end(error) -----------"); XxlJobLogger.log("<br>----------- JobThread Exception:" + errorMsg + "<br>----------- xxl-job job execute end(error) -----------");
} finally { } finally {
if (singleThread != null) {
singleThread.shutdown();
}
if(triggerParam != null) { if(triggerParam != null) {
// callback handler info // callback handler info
if (!toStop) { if (!toStop) {

Loading…
Cancel
Save