Skip to content

Commit

Permalink
任务地址支持配置多个,进行failover
Browse files Browse the repository at this point in the history
  • Loading branch information
xueli.xue committed May 28, 2016
1 parent e58f77d commit 71e1227
Show file tree
Hide file tree
Showing 23 changed files with 620 additions and 449 deletions.
15 changes: 10 additions & 5 deletions db/tables_xxl_job.sql
Original file line number Diff line number Diff line change
Expand Up @@ -150,17 +150,19 @@ CREATE TABLE `xxl_job_qrtz_trigger_info` (
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN',
`job_desc` varchar(255) NOT NULL,
`job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
`job_data` varchar(512) DEFAULT NULL COMMENT '任务执行数据',
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`alarm_threshold` int(11) DEFAULT NULL COMMENT '报警阀值(连续失败次数)',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,有多个则逗号分隔',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(255) DEFAULT NULL COMMENT '执行器任务参数',
`glue_switch` int(11) DEFAULT '0' COMMENT 'GLUE模式开关:0-否,1-是',
`glue_source` text COMMENT 'GLUE源代码',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
PRIMARY KEY (`id`)
);
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `xxl_job_qrtz_trigger_log` (
`id` int(11) NOT NULL AUTO_INCREMENT,
Expand All @@ -169,15 +171,17 @@ CREATE TABLE `xxl_job_qrtz_trigger_log` (
`job_cron` varchar(128) NOT NULL COMMENT '任务执行CORN表达式',
`job_desc` varchar(255) NOT NULL,
`job_class` varchar(255) NOT NULL COMMENT '任务执行JobBean',
`job_data` varchar(512) DEFAULT NULL COMMENT '任务执行数据',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(255) DEFAULT NULL COMMENT 'executor_param',
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
`trigger_status` varchar(255) DEFAULT NULL COMMENT '调度-结果',
`trigger_msg` varchar(2048) DEFAULT NULL COMMENT '调度-日志',
`handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
`handle_status` varchar(255) DEFAULT NULL COMMENT '执行-状态',
`handle_msg` varchar(2048) DEFAULT NULL COMMENT '执行-日志',
PRIMARY KEY (`id`)
);
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8;

CREATE TABLE `xxl_job_qrtz_trigger_logglue` (
`id` int(11) NOT NULL AUTO_INCREMENT,
Expand All @@ -188,7 +192,8 @@ CREATE TABLE `xxl_job_qrtz_trigger_logglue` (
`add_time` timestamp NULL DEFAULT NULL,
`update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ;
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;



commit;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,18 @@
package com.xxl.job.admin.controller;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.quartz.CronExpression;
import org.quartz.SchedulerException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.xxl.job.admin.core.constant.Constants.JobGroupEnum;
import com.xxl.job.admin.core.jobbean.RemoteHttpJobBean;
import com.xxl.job.admin.core.model.ReturnT;
import com.xxl.job.admin.core.model.XxlJobInfo;
import com.xxl.job.admin.core.util.DynamicSchedulerUtil;
import com.xxl.job.admin.dao.IXxlJobInfoDao;
import com.xxl.job.admin.dao.IXxlJobLogDao;
import com.xxl.job.admin.dao.IXxlJobLogGlueDao;
import com.xxl.job.core.handler.HandlerRepository;
import com.xxl.job.core.util.JacksonUtil;
import com.xxl.job.admin.service.IXxlJobService;

/**
* index controller
Expand All @@ -35,11 +23,7 @@
public class JobInfoController {

@Resource
private IXxlJobInfoDao xxlJobInfoDao;
@Resource
public IXxlJobLogDao xxlJobLogDao;
@Resource
private IXxlJobLogGlueDao xxlJobLogGlueDao;
private IXxlJobService xxlJobService;

@RequestMapping
public String index(Model model) {
Expand All @@ -53,219 +37,52 @@ public Map<String, Object> pageList(@RequestParam(required = false, defaultValue
@RequestParam(required = false, defaultValue = "10") int length,
String jobGroup, String jobName, String filterTime) {

// page list
List<XxlJobInfo> list = xxlJobInfoDao.pageList(start, length, jobGroup, jobName);
int list_count = xxlJobInfoDao.pageListCount(start, length, jobGroup, jobName);

// fill job info
if (list!=null && list.size()>0) {
for (XxlJobInfo jobInfo : list) {
DynamicSchedulerUtil.fillJobInfo(jobInfo);
}
}

// package result
Map<String, Object> maps = new HashMap<String, Object>();
maps.put("recordsTotal", list_count); // 总记录数
maps.put("recordsFiltered", list_count); // 过滤后的总记录数
maps.put("data", list); // 分页列表
return maps;
return xxlJobService.pageList(start, length, jobGroup, jobName, filterTime);
}

@RequestMapping("/add")
@ResponseBody
public ReturnT<String> add(String jobGroup, String jobName, String jobCron, String jobDesc,
String handler_address, String handler_name, String handler_params,
String executorAddress, String executorHandler, String executorParam,
String author, String alarmEmail, int alarmThreshold,
int glueSwitch, String glueSource, String glueRemark) {

// valid
if (JobGroupEnum.match(jobGroup) == null) {
return new ReturnT<String>(500, "请选择“任务组”");
}
if (StringUtils.isBlank(jobName)) {
return new ReturnT<String>(500, "请输入“任务名”");
}
if (!CronExpression.isValidExpression(jobCron)) {
return new ReturnT<String>(500, "“corn”不合法");
}
if (StringUtils.isBlank(jobDesc)) {
return new ReturnT<String>(500, "请输入“任务描述”");
}
if (StringUtils.isBlank(handler_address)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (glueSwitch==0 && StringUtils.isBlank(handler_name)) {
return new ReturnT<String>(500, "请输入“jobHandler”");
}
if (StringUtils.isBlank(author)) {
return new ReturnT<String>(500, "请输入“负责人”");
}
if (StringUtils.isBlank(alarmEmail)) {
return new ReturnT<String>(500, "请输入“报警邮件”");
}
if (alarmThreshold < 0) {
alarmThreshold = 0;
}

try {
if (DynamicSchedulerUtil.checkExists(jobName, jobGroup)) {
return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
}
} catch (SchedulerException e1) {
e1.printStackTrace();
return new ReturnT<String>(500, "此任务已存在,请更换任务组或任务名");
}

// parse jobDataMap
HashMap<String, String> jobDataMap = new HashMap<String, String>();
jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);

// Backup to the database
XxlJobInfo jobInfo = new XxlJobInfo();
jobInfo.setJobGroup(jobGroup);
jobInfo.setJobName(jobName);
jobInfo.setJobCron(jobCron);
jobInfo.setJobDesc(jobDesc);
jobInfo.setJobClass(RemoteHttpJobBean.class.getName());
jobInfo.setJobData(JacksonUtil.writeValueAsString(jobDataMap));
jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setAlarmThreshold(alarmThreshold);
jobInfo.setGlueSwitch(glueSwitch);
jobInfo.setGlueSource(glueSource);
jobInfo.setGlueRemark(glueRemark);
xxlJobInfoDao.save(jobInfo);

try {
// add job 2 quartz
boolean result = DynamicSchedulerUtil.addJob(jobInfo);
if (result) {
return ReturnT.SUCCESS;
} else {
xxlJobInfoDao.delete(jobGroup, jobName);
return new ReturnT<String>(500, "新增任务失败");
}
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
return xxlJobService.add(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorHandler, executorParam,
author, alarmEmail, alarmThreshold, glueSwitch, glueSource, glueRemark);
}

@RequestMapping("/reschedule")
@ResponseBody
public ReturnT<String> reschedule(String jobGroup, String jobName, String jobCron, String jobDesc,
String handler_address, String handler_name, String handler_params,
String executorAddress, String executorHandler, String executorParam,
String author, String alarmEmail, int alarmThreshold, int glueSwitch) {

// valid
if (JobGroupEnum.match(jobGroup) == null) {
return new ReturnT<String>(500, "请选择“任务组”");
}
if (StringUtils.isBlank(jobName)) {
return new ReturnT<String>(500, "请输入“任务名”");
}
if (!CronExpression.isValidExpression(jobCron)) {
return new ReturnT<String>(500, "“corn”不合法");
}
if (StringUtils.isBlank(jobDesc)) {
return new ReturnT<String>(500, "请输入“任务描述”");
}
if (StringUtils.isBlank(handler_address)) {
return new ReturnT<String>(500, "请输入“执行器地址”");
}
if (glueSwitch==0 && StringUtils.isBlank(handler_name)) {
return new ReturnT<String>(500, "请输入“jobHandler”");
}
if (StringUtils.isBlank(author)) {
return new ReturnT<String>(500, "请输入“负责人”");
}
if (StringUtils.isBlank(alarmEmail)) {
return new ReturnT<String>(500, "请输入“报警邮件”");
}
if (alarmThreshold < 0) {
alarmThreshold = 0;
}

// parse jobDataMap
HashMap<String, String> jobDataMap = new HashMap<String, String>();
jobDataMap.put(HandlerRepository.HANDLER_ADDRESS, handler_address);
jobDataMap.put(HandlerRepository.HANDLER_NAME, handler_name);
jobDataMap.put(HandlerRepository.HANDLER_PARAMS, handler_params);

XxlJobInfo jobInfo = xxlJobInfoDao.load(jobGroup, jobName);
jobInfo.setJobCron(jobCron);
jobInfo.setJobDesc(jobDesc);
jobInfo.setJobData(JacksonUtil.writeValueAsString(jobDataMap));
jobInfo.setAuthor(author);
jobInfo.setAlarmEmail(alarmEmail);
jobInfo.setAlarmThreshold(alarmThreshold);
jobInfo.setGlueSwitch(glueSwitch);

try {
// fresh quartz
DynamicSchedulerUtil.rescheduleJob(jobInfo);

// fresh db
xxlJobInfoDao.update(jobInfo);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
return xxlJobService.reschedule(jobGroup, jobName, jobCron, jobDesc, executorAddress, executorHandler, executorParam, author,
alarmEmail, alarmThreshold, glueSwitch);
}

@RequestMapping("/remove")
@ResponseBody
public ReturnT<String> remove(String jobGroup, String jobName) {
try {
DynamicSchedulerUtil.removeJob(jobName, jobGroup);
xxlJobInfoDao.delete(jobGroup, jobName);
xxlJobLogDao.delete(jobGroup, jobName);
xxlJobLogGlueDao.delete(jobGroup, jobName);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
}
return ReturnT.FAIL;
return xxlJobService.remove(jobGroup, jobName);
}

@RequestMapping("/pause")
@ResponseBody
public ReturnT<String> pause(String jobGroup, String jobName) {
try {
DynamicSchedulerUtil.pauseJob(jobName, jobGroup); // jobStatus do not store
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
return xxlJobService.pause(jobGroup, jobName);
}

@RequestMapping("/resume")
@ResponseBody
public ReturnT<String> resume(String jobGroup, String jobName) {
try {
DynamicSchedulerUtil.resumeJob(jobName, jobGroup);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
return xxlJobService.resume(jobGroup, jobName);
}

@RequestMapping("/trigger")
@ResponseBody
public ReturnT<String> triggerJob(String jobGroup, String jobName) {
try {
DynamicSchedulerUtil.triggerJob(jobName, jobGroup);
return ReturnT.SUCCESS;
} catch (SchedulerException e) {
e.printStackTrace();
return ReturnT.FAIL;
}
return xxlJobService.triggerJob(jobGroup, jobName);
}

}
Loading

0 comments on commit 71e1227

Please sign in to comment.