非原创,原博客我找不着了,所以自个写个记录一下
xxl-job版本:2.3.0
一、配置bootstrap.yml
xxl:
job:
admin:
enable: true
address: http://192.168.xxx.xxx:28080/xxl-job-admin
username: admin
password: 123456
accessToken:
executor:
appname: xxx-executor
address:
ip:
port: 29998
logpath: /data/applogs/xxl_job/jobHandler
logretentiondays: 3
二、后端代码实现xxl-job-admin的登录和crud接口
1.配置类(共3个)
1.1 XxlJobAdminProperties
@Data
@ConfigurationProperties(prefix = "xxl.job.admin")
public class XxlJobAdminProperties {
private String address;
private String username;
private String password ;
private int connectionTimeOut = 5000;
private boolean enable = false;
}
1.2 XxlJobConfig
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
@Slf4j
public class XxlJobConfig {
@Value("${xxl.job.admin.address}")
private String adminAddress;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.appname}")
private String appName;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Value("${xxl.job.accessToken}")
private String token;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddress);
xxlJobSpringExecutor.setAppname(appName);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(token);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
* <dependency>
* <groupId>org.springframework.cloud</groupId>
* <artifactId>spring-cloud-commons</artifactId>
* <version>${version}</version>
* </dependency>
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
1.3 XxlJobAdminAutoConfigure
@Configuration
@ConditionalOnClass(XxlJobDataService.class)
@EnableConfigurationProperties(XxlJobAdminProperties.class)
@Slf4j
public class XxlJobAdminAutoConfigure {
@Bean
@ConditionalOnProperty(prefix = "xxl.job.admin",value = "enable",havingValue = "true")
public XxlJobDataService xxlJobService(HttpHeader loginHeader, XxlJobAdminProperties xxlJobAdminProperties) {
XxlJobDataService xxlJobDataService = new XxlJobDataServiceImpl(loginHeader, xxlJobAdminProperties);
return xxlJobDataService;
}
@Bean
@ConditionalOnProperty(prefix = "xxl.job.admin",value = "enable",havingValue = "true")
public XxlJobGroupService xxlJobGroupService(HttpHeader loginHeader, XxlJobAdminProperties xxlJobAdminProperties) {
XxlJobGroupService xxlJobGroupService=new XxlJobGroupServiceImpl(loginHeader, xxlJobAdminProperties);
return xxlJobGroupService;
}
@Bean("loginHeader")
@ConditionalOnProperty(prefix = "xxl.job.admin",value = "enable",havingValue = "true")
public HttpHeader httpRequest(XxlJobAdminProperties xxlJobAdminProperties){
String adminUrl = xxlJobAdminProperties.getAddress();
String userName = xxlJobAdminProperties.getUsername();
String password = xxlJobAdminProperties.getPassword();
int connectionTimeOut = xxlJobAdminProperties.getConnectionTimeOut();
Map<String, Object > paramMap = new HashMap<>();
paramMap.put("userName",userName);
paramMap.put("password",password);
HttpResponse httpResponse = null;
try{
httpResponse = HttpRequest.post(adminUrl+"/login").form(paramMap).timeout(connectionTimeOut).execute();
}catch (Exception e){
log.error("登录失败...");
log.error(e.getMessage());
}
int status = httpResponse.getStatus();
if (200 != status) {
throw new RuntimeException("登录失败");
}
String body = httpResponse.body();
ReturnT returnT = JSONUtil.toBean(body, ReturnT.class);
if (200 != returnT.getCode()) {
throw new RuntimeException("登录失败:"+returnT.getMsg());
}
String cookieName = "XXL_JOB_LOGIN_IDENTITY";
HttpCookie cookie = httpResponse.getCookie(cookieName);
if (cookie == null) {
throw new RuntimeException("没有获取到登录成功的cookie,请检查登录连接或者参数是否正确");
}
String headerValue = new StringBuilder(cookieName).append("=").append(cookie.getValue()).toString();
HttpHeader loginHeader = new HttpHeader("Cookie",headerValue);
return loginHeader;
}
}
2.实体和vo类(共4个)
2.1 XxlJobInfo
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class XxlJobInfo {
private int id; // 主键ID
private int jobGroup; // 执行器主键ID
private String jobDesc;
private Date addTime;
private Date updateTime;
private String author; // 负责人
private String alarmEmail; // 报警邮件
private String scheduleType; // 调度类型
private String scheduleConf; // 调度配置,值含义取决于调度类型
private String misfireStrategy; // 调度过期策略
private String executorRouteStrategy; // 执行器路由策略
private String executorHandler; // 执行器,任务Handler名称
private String executorParam; // 执行器,任务参数
private String executorBlockStrategy; // 阻塞处理策略
private int executorTimeout; // 任务执行超时时间,单位秒
private int executorFailRetryCount; // 失败重试次数
private String glueType; // GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
private String glueSource; // GLUE源代码
private String glueRemark; // GLUE备注
private Date glueUpdatetime; // GLUE更新时间
private String childJobId; // 子任务ID,多个逗号分隔
private int triggerStatus; // 调度状态:0-停止,1-运行
private long triggerLastTime; // 上次调度时间
private long triggerNextTime; // 下次调度时间
}
2.2 JobInfoPageItem
@Data
public class JobInfoPageItem {
private int triggerLastTime;
private String alarmEmail;
private String glueUpdatetime;
private String executorParam;
private String addTime;
private String executorBlockStrategy;
private String author;
private String scheduleConf;
private String executorRouteStrategy;
private int triggerStatus;
private String childJobId;
private long triggerNextTime;
private String updateTime;
private int jobGroup;
private String glueRemark;
private String jobDesc;
private String glueSource;
private String misfireStrategy;
private String scheduleType;
private String glueType;
private String executorHandler;
private int executorFailRetryCount;
private int id;
private int executorTimeout;
}
2.3 JobGroupPageResult
@Data
public class JobGroupPageResult {
private int recordsFiltered; // 过滤后的总记录数
private List<JoGroupPageItem> data; // 分页列表
private int recordsTotal; // 总记录数
@Data
public static class JoGroupPageItem{
private int id;
private String appname;
private String title;
private int addressType; // 执行器地址类型:0=自动注册、1=手动录入
private String addressList; // 执行器地址列表,多地址逗号分隔(手动录入)
private Date updateTime;
}
}
2.4 JobInfoPageResult
@Data
public class JobInfoPageResult {
private int recordsFiltered;
private List<JobInfoPageItem> data;
private int recordsTotal;
}
3.服务类(共2个)
3.1 XxlJobDataService
(1)接口类XxlJobDataService
public interface XxlJobDataService {
String jobAddPath = "/jobinfo/add";
String jobDeletePath = "/jobinfo/remove";
String jobUpdatePath = "/jobinfo/update";
String jobStartPath = "/jobinfo/start";
String jobStopPath = "/jobinfo/stop";
String jobTriggerPath = "/jobinfo/trigger";
String jobPageListPath = "/jobinfo/pageList";
String jobNextTriggerTimePath = "/jobinfo/nextTriggerTime";
JobInfoPageResult pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author);
/**
* add job
*
* @param jobInfo
* @return
*/
String add(XxlJobInfo jobInfo);
/**
* update job
*
* @param jobInfo
* @return
*/
void update(XxlJobInfo jobInfo);
/**
* remove job
* *
* @param id
* @return
*/
void remove(int id);
void remove(int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author);
void removeAll(int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author);
/**
* 停止运行中的任务并删除
*/
void cancel(int jobGroup, String jobDesc, String executorHandler, String author);
void cancelAll(int jobGroup, String jobDesc, String executorHandler, String author);
/**
* start job
*
* @param id
* @return
*/
void start(int id);
/**
* stop job
*
* @param id
* @return
*/
void stop(int id);
void triggerJob(int id, String executorParam, String addressList);
List<String> nextTriggerTime(String scheduleType, String scheduleConf);
}
(2)实现类XxlJobDataServiceImpl
@Service
@Slf4j
public class XxlJobDataServiceImpl implements XxlJobDataService {
private HttpHeader loginHeader;
private XxlJobAdminProperties xxlJobAdminProperties;
private int timeout;
public XxlJobDataServiceImpl(HttpHeader loginHeader, XxlJobAdminProperties xxlJobAdminProperties) {
this.loginHeader = loginHeader;
this.xxlJobAdminProperties = xxlJobAdminProperties;
this.timeout = this.xxlJobAdminProperties.getConnectionTimeOut();
}
@Override
public JobInfoPageResult pageList(int start, int length, int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) {
HttpRequest httpRequest = this.getHttpRequest(jobPageListPath);
Map<String, Object> paramMap = new HashMap();
paramMap.put("start", start);
paramMap.put("length", length);
paramMap.put("jobGroup", jobGroup);
paramMap.put("triggerStatus", triggerStatus);
paramMap.put("jobDesc", jobDesc);
paramMap.put("executorHandler", executorHandler);
paramMap.put("author", author);
HttpResponse response = httpRequest.form(paramMap).timeout(timeout).execute();
int status = response.getStatus();
String body = response.body();
// Assert.isTrue(status==200);
JobInfoPageResult jobInfoPageResult = JSON.parseObject(body, JobInfoPageResult.class);
return jobInfoPageResult;
}
@Override
public String add(XxlJobInfo jobInfo) {
HttpRequest httpRequest = postHttpRequest(jobAddPath);
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(jobInfo));
ReturnT<String> returnT = requestXxlJobAdmin(httpRequest, jsonObject, new TypeReference<ReturnT<String>>() {
});
return returnT.getContent();
}
@Override
public void update(XxlJobInfo jobInfo) {
HttpRequest httpRequest = postHttpRequest(jobUpdatePath);
JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(jobInfo));
requestXxlJobAdmin(httpRequest, jsonObject, new TypeReference<ReturnT<String>>() {
});
}
@Override
public void remove(int id) {
HttpRequest httpRequest = postHttpRequest(jobDeletePath);
Map<String, Object> map = new HashMap<>();
map.put("id", id);
requestXxlJobAdmin(httpRequest, map, new TypeReference<ReturnT<String>>() {
});
}
@Override
public void remove(int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) {
JobInfoPageResult jobInfoPageResult = this.pageList(0, 1, jobGroup, triggerStatus, jobDesc, executorHandler, author);
List<JobInfoPageItem> data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.remove(item.getId());
}
}
@Override
public void removeAll(int jobGroup, int triggerStatus, String jobDesc, String executorHandler, String author) {
JobInfoPageResult jobInfoPageResult = this.pageList(0, 10, jobGroup, triggerStatus, jobDesc, executorHandler, author);
List<JobInfoPageItem> data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.remove(item.getId());
}
int i = 1;
while (data.size() > 10) {
data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.remove(item.getId());
}
jobInfoPageResult = this.pageList(i++, 10, jobGroup, triggerStatus, jobDesc, executorHandler, author);
}
}
@Override
public void cancel(int jobGroup, String jobDesc, String executorHandler, String author) {
JobInfoPageResult jobInfoPageResult = this.pageList(0, 1, jobGroup, 1, jobDesc, executorHandler, author);
List<JobInfoPageItem> data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.stop(item.getId());
}
}
@Override
public void cancelAll(int jobGroup, String jobDesc, String executorHandler, String author) {
JobInfoPageResult jobInfoPageResult = this.pageList(0, 10, jobGroup, 1, jobDesc, executorHandler, author);
List<JobInfoPageItem> data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.remove(item.getId());
}
int i = 1;
while (data.size() > 10) {
data = jobInfoPageResult.getData();
if (CollUtil.isEmpty(data)) {
return;
}
for (JobInfoPageItem item : data) {
this.remove(item.getId());
}
jobInfoPageResult = this.pageList(i++, 10, jobGroup, 1, jobDesc, executorHandler, author);
}
}
@Override
public void start(int id) {
HttpRequest httpRequest = postHttpRequest(jobStartPath);
Map<String, Object> map = new HashMap<>();
map.put("id", id);
requestXxlJobAdmin(httpRequest, map, new TypeReference<ReturnT<String>>() {
});
}
@Override
public void stop(int id) {
HttpRequest httpRequest = postHttpRequest(jobStopPath);
Map<String, Object> map = new HashMap<>();
map.put("id", id);
requestXxlJobAdmin(httpRequest, map, new TypeReference<ReturnT<String>>() {
});
}
@Override
public void triggerJob(int id, String executorParam, String addressList) {
HttpRequest httpRequest = postHttpRequest(jobTriggerPath);
Map<String, Object> map = new HashMap<>();
map.put("id", id);
map.put("executorParam", executorParam);
map.put("addressList", addressList);
requestXxlJobAdmin(httpRequest, map, new TypeReference<ReturnT<String>>() {
});
}
@Override
public List<String> nextTriggerTime(String scheduleType, String scheduleConf) {
HttpRequest httpRequest = getHttpRequest(jobNextTriggerTimePath);
Map<String, Object> map = new HashMap<>();
map.put("scheduleType", scheduleType);
map.put("scheduleConf", scheduleConf);
ReturnT<List<String>> returnT = requestXxlJobAdmin(httpRequest, map, new TypeReference<ReturnT<List<String>>>() {
});
return returnT.getContent();
}
private HttpRequest postHttpRequest(String path) {
String url = new StringBuilder(xxlJobAdminProperties.getAddress()).append(path).toString();
HttpRequest httpRequest = HttpRequest.post(url);
httpRequest.header(loginHeader.getHeaderName(), loginHeader.getHeaderValue());
return httpRequest;
}
private HttpRequest getHttpRequest(String path) {
String url = new StringBuilder(xxlJobAdminProperties.getAddress()).append(path).toString();
HttpRequest httpRequest = HttpRequest.get(url);
httpRequest.header(loginHeader.getHeaderName(), loginHeader.getHeaderValue());
return httpRequest;
}
@SneakyThrows
private <T extends ReturnT> T requestXxlJobAdmin(HttpRequest httpRequest, Map<String, Object> paramMap, TypeReference<T> type) {
HttpResponse response = httpRequest.form(paramMap).timeout(timeout).execute();
int status = response.getStatus();
String body = response.body();
T returnT = JSON.parseObject(body, type);
if (status != 200) {
throw new Exception("requestXxlJobAdmin Exception:" + returnT.getMsg());
}
// Assert.isTrue(status == 200,returnT.getMsg());
return returnT;
}
}
3.2 XxlJobGroupService
(1)接口类XxlJobGroupService
public interface XxlJobGroupService {
String jobGroupPageListPath = "/jobgroup/pageList";
JobGroupPageResult jobGroupPageList(int start, int length, String appname, String title);
/**
* 根据执行器appName获取groupId
* @param appName 默认返回list中第一个
* @return
*/
int getGroupId(String appName);
}
(2)实现类XxlJobGroupServiceImpl
@Service
@Slf4j
public class XxlJobGroupServiceImpl implements XxlJobGroupService {
private HttpHeader loginHeader;
private XxlJobAdminProperties xxlJobAdminProperties;
private int timeout;
public XxlJobGroupServiceImpl(HttpHeader loginHeader, XxlJobAdminProperties xxlJobAdminProperties) {
this.loginHeader = loginHeader;
this.xxlJobAdminProperties = xxlJobAdminProperties;
this.timeout = this.xxlJobAdminProperties.getConnectionTimeOut();
}
@Override
public JobGroupPageResult jobGroupPageList(int start, int length, String appname, String title) {
HttpRequest httpRequest = this.getHttpRequest(jobGroupPageListPath);
Map<String, Object> paramMap = new HashMap();
paramMap.put("start", start);
paramMap.put("length", length);
paramMap.put("appname", appname);
paramMap.put("title", title);
HttpResponse response = httpRequest.form(paramMap).timeout(timeout).execute();
int status = response.getStatus();
String body = response.body();
if(status!=200){
log.error("获取到的jobGroup是null...,错误码:{}",status);
return null;
}
JobGroupPageResult jobGroupPageResult = JSON.parseObject(body, JobGroupPageResult.class);
return jobGroupPageResult;
}
private HttpRequest getHttpRequest(String path) {
String url = new StringBuilder(xxlJobAdminProperties.getAddress()).append(path).toString();
HttpRequest httpRequest = HttpRequest.get(url);
httpRequest.header(loginHeader.getHeaderName(), loginHeader.getHeaderValue());
return httpRequest;
}
/**
* 根据appName获取groupId
* @param appName 默认返回list中第一个
* @return
*/
@Override
public int getGroupId(String appName){
JobGroupPageResult jobGroupPageResult = jobGroupPageList(0,100,appName,null);
List<JobGroupPageResult.JoGroupPageItem> data=jobGroupPageResult.getData();
if(CollectionUtils.isEmpty(data)){
return -1; //未找到
}
JobGroupPageResult.JoGroupPageItem item=data.get(0);
return item.getId();
}
}
三、接口调用
@Qualifier("xxlJobDataServiceImpl")
@Autowired
private XxlJobDataService xxlJobDataService;
@Qualifier("xxlJobGroupServiceImpl")
@Autowired
private XxlJobGroupService xxlJobGroupService;
private void addJobInfo(XxlJobInfo jobInfo){
String add = xxlJobDataService.add(jobInfo);
}