Handler
为餐桌上的食物
,可视化界面则可以决定哪个执行器(人),吃东西或者不吃某个东西(定时任务),在什么时间吃(Corn表达式控制或者执行或终止或者;立即开始);XXL-JOB弥补了Quartz的上述不足之处。
常规的Quartz的开发,任务逻辑一般维护在QuartzJobBean中,耦合很严重。
XXL-JOB中“调度模块”和“任务模块”完全解耦,调度模块中的所有调度任务使用同一个QuartzJobBean,即RemoteHttpJobBean。不同的调度任务将各自的调度参数维护在各自的扩展表数据中,当触发RemoteHttpJobBean执行时,将会解析不同的调度参数发起远程调用,调用各自的远程执行器服务。
这种调用模型类似RPC调用,RemoteHttpJobBean提供调用代理的功能,而执行器提供远程服务的功能。
XL-JOB将调度行为抽象形成“调度中心”公共平台,而平台自身并不承担业务逻辑,“调度中心”只负责发起调度请求。
将任务抽象成分散的JobHandler,交由“执行器”统一管理,“执行器”负责接收调度请求并执行对应的JobHandler中的业务逻辑。
因此,“调度”和“任务”两部分可以解耦成调度模块和执行模块,提高业务系统的整体稳定性和扩展性:
调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统的性能不再受限于任务模块;支持可视化、简单且动态的管理调度信息,包括任务的新建、更新、删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。
执行模块(执行器):负责接收调度请求并执行任务逻辑。任务模块专注于任务的执行等操作,开发和维护更加简单和高效;接收“调度中心”的执行请求、终止请求和日志请求等。
<!-- xxl-job-core -->
<dependency>
<groupId>com.cdmtc</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.0.2</version>
</dependency>
修改了端口号为8888,所以这里的record.xxl.job.admin.address可视化界面配置的端口号改为了8888 executor: 执行器的配置信息
xxl.job.admin.addresses 调度中心的部署地址。若调度中心采用集群部署,存在多个地址,则用逗号分隔。执行器将会使用该地址进行”执行器心跳注册”和”任务结果回调”。
xxl.job.executor.appname 执行器的应用名称,它是执行器心跳注册的分组依据。
xxl.job.executor.ip 执行器的IP地址,用于”调度中心请求并触发任务”和”执行器注册”。执行器IP默认为空,表示自动获取IP。多网卡时可手动设置指定IP,手动设置IP时将会绑定Host。
xxl.job.executor.port 执行器的端口号,默认值为9999。单机部署多个执行器时,注意要配置不同的执行器端口。
xxl.job.accessToken 执行器的通信令牌,非空时启用。
xxl.job.executor.logpath 执行器输出的日志文件的存储路径,需要拥有该路径的读写权限。
xxl.job.executor.logretentiondays 执行器日志文件的定期清理功能,指定日志保存天数,日志文件过期自动删除。限制至少保存3天,否则功能不生效。
注意,XXL-JOB执行器的配置文件也可以交给Disconf进行托管。
package com.cdmtc.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${record.xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${record.xxl.job.executor.appname}")
private String appName;
@Value("${record.xxl.job.executor.ip}")
private String ip;
@Value("${record.xxl.job.executor.port}")
private int port;
@Value("${record.xxl.job.accessToken}")
private String accessToken;
@Value("${record.xxl.job.executor.logpath}")
private String logPath;
@Value("${record.xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppName(appName);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
*
* org.springframework.cloud
* spring-cloud-commons
* ${version}
*
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
这是一个执行器配置类,用来读取执行器的配置信息
XxlJobConfig配置类有两点需要注意:
组件扫描
获取执行器实例
可修改为其他账号密码
如需配置集群等其他操作可参考官方文档
如果没有点击停止按钮的话,则会一直是启动状态,如果点击了停止按钮,则定时任务停止,Corn表达式不再生效;
11.如果点击编辑,则进入定时任务的更新页面
注意,AppName的取值应该和示例工程的application.properties文件中的xxl.job.executor.appname字段的取值相同,注册方式应该选择自动注册。新增完成之后,就可以在执行器列表中看到新建的执行器, 而我在写入的时候将applcation.properties替换为了bootstrap.yml,但内容不变;
调度中心会每隔15分钟调度一次这个任务。
Step-2 开发任务代码
在任务列表中选中指定的GLUE(Java)任务,点击该任务右侧的“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。
版本回溯功能:在GLUE任务的Web IDE界面,选择右上角下拉框“版本回溯”,会列出该GLUE任务的更新历史(支持30个版本的版本回溯),选择相应版本即可显示该版本代码,保存后GLUE代码即回退到对应的历史版本。GLUE任务代码和Web IDE界面,如下图所示:
执行器集群部署时,任务路由策略选择“分片广播”的情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时传递分片参数,可以根据分片参数开发分片任务。
“分片广播”以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
“分片广播”和普通任务开发流程一致,不同之处在于可以获取分片参数,通过分片参数进行分片业务处理。开发流程如下:
Step-1 开发JobHandler代码
@JobHandler(value="shardingJobHandler")
@Service
public class ShardingJobHandler extends IJobHandler {
@Override
public ReturnT<String> execute(String param) throws Exception {
// 分片参数
ShardingUtil.ShardingVO shardingVO = ShardingUtil.getShardingVo();
XxlJobLogger.log("分片参数:当前分片序号 = {0}, 总分片数 = {1}", shardingVO.getIndex(), shardingVO.getTotal());
// 业务逻辑
for (int i = 0; i < shardingVO.getTotal(); i++) {
if (i == shardingVO.getIndex()) {
XxlJobLogger.log("第 {0} 片, 命中分片开始处理", i);
} else {
XxlJobLogger.log("第 {0} 片, 忽略", i);
}
}
return SUCCESS;
}
}
上述代码的第9行获取分片参数,第10行获取分片参数的两个属性:
Step-2 新建调度任务
调度中心会每隔15分钟广播调度一次shardingJobHandler任务(因为Corn表达式设置了15分钟执行一次)。
查看调度日志
查看执行日志
终止运行中的任务
这项功能只针对执行中的任务。在任务日志页面,点击右侧的“终止任务”按钮,将会向本次任务对应的执行器发送任务终止请求,将会终止掉本次任务,同时会清空掉整个任务执行队列,如下图所示:
任务终止是通过“interrupt”执行线程的方式实现的,将会触发“InterruptedException”异常。因此,如果JobHandler内部捕获到该异常并消化掉的话,任务终止功能将不起作用。
因此, 如果遇到上述任务终止不起作用的情况, 需要在JobHandler中针对“InterruptedException”异常进行特殊处理(向上抛出)。另外,在JobHandler中开启子线程时,子线程也不可捕获处理“InterruptedException”,应该主动向上抛出。
概述: 当定时任务执行失败的时候,日志会自动记录失败结果,并且在cdmtc.xxl-job里面的application.properties中配置了email邮箱时,可邮件提醒;
开启短信提醒功能,需要从邮箱中获取授权码,每个邮箱的获取方式可能不同,可具体百度;qq邮箱为从 设置 按钮中的 账户 ,然后选择POP3/SMTP 服务,点击开启,按提示获取授权码即可;
授权码就是配置文件中的password
<?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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<groupId>com.demo</groupId>
<artifactId>springboot_quick</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<xdocreport.version>1.0.5</xdocreport.version>
</properties>
<dependencies>
<!--web功能的起步依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
/**
* create by: zhanglei
*/
//@EnableFeignClients
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) {
SpringApplication.run(MySpringBootApplication.class);
}
@Bean
RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
}
import com.demo.MySpringBootApplication;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
/**
* @create_by: zhanglei
* @craete_time 2019/7/2
*/
@SpringBootTest(classes = MySpringBootApplication.class)
@RunWith(SpringRunner.class)
public class TestDemo {
@Test
public void test() {
System.out.println("hello,world");
}
@Autowired
private RestTemplate restTemplate;
/* Cookie 是根据用户名密码生成的,基本不变,可直接保存数据库或者Redis,然后读取即不必反复登录 */
/* Cookie 如果后期Cookie有失效时间了,则可用定时任务定时刷新或者失效重登重新保存即可 */
/**
* 模拟登录并拿到Cookie
*/
@Test
public void login(){
HttpHeaders headers = new HttpHeaders();
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("userName", "admin");
map.add("password","123456");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/login", request, String.class);
System.out.println(response.getHeaders().get("Set-Cookie").get(0)); // XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly
}
/* 组操作---> 对执行器进行操作 */
/**
* 保存组Group
*/
@Test
public void saveGroup(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("appName", "xxl-job-executor-cdmtc-record"); //应用名称
map.add("title", "测试执行器"); //执行器名称
map.add("order", "1"); //排序方式
map.add("addressType", "1"); //注册方式 : 0为
map.add("addressList", "10.4.7.214:9999,10.4.7.214:9999"); //多地址逗号分隔
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobgroup/save", request, String.class);
System.out.println(response.getBody()); // {"code":200,"msg":null,"content":null} 返回此,且数据库增加数据即为成功
}
/**
* 修改组
*/
@Test
public void updateGroup(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","4"); //修改的,id一定不能为空
map.add("appName", "xxl-job-executor-cdmtc-record"); //应用名称
map.add("title", "测试执行器323223"); //执行器名称
map.add("order", "1"); //排序方式
map.add("addressType", "1"); //注册方式 : 0为
map.add("addressList", "10.4.7.214:9999"); //多地址逗号分隔
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobgroup/update", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/**
* 删除组
*/
@Test
public void removeGroup(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","4"); //删除的,id一定不能为空
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobgroup/remove", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/* 定时任务操作:查询,新增,编辑,启动,停止,删除等*/
/**
* 获取指定的执行器下的任务列表
*/
@Test
public void pageList(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("jobGroup", "2");
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/pageList", request, String.class);
System.out.println(response.getBody()); //{"recordsFiltered":4,"data":[{"id":13,"jobGroup":2,"jobCron":"0/1 * * * * ? ","jobDesc":"测试HelloWorld","addTime":1561687650000,"updateTime":1562037928000,"author":"zhanglei","alarmEmail":"[email protected]","executorRouteStrategy":"FIRST","executorHandler":"firstJobHandler","executorParam":"456464564","executorBlockStrategy":"SERIAL_EXECUTION","executorTimeout":0,"executorFailRetryCount":0,"glueType":"BEAN","glueSource":"","glueRemark":"GLUE代码初始化","glueUpdatetime":1561687650000,"childJobId":"","jobStatus":"NONE"},{"id":12,"jobGroup":2,"jobCron":"0/1 * * * * ? ","jobDesc":"测试HelloWorld","addTime":1561612429000,"updateTime":1561612429000,"author":"zhanglei","alarmEmail":"","executorRouteStrategy":"FIRST","executorHandler":"firstJobHandler","executorParam":"","executorBlockStrategy":"SERIAL_EXECUTION","executorTimeout":0,"executorFailRetryCount":0,"glueType":"BEAN","glueSource":"","glueRemark":"GLUE代码初始化","glueUpdatetime":1561612429000,"childJobId":"","jobStatus":"NONE"},{"id":4,"jobGroup":2,"jobCron":"0/1 * * * * ? ","jobDesc":"测试任务1","addTime":1561538414000,"updateTime":1561538431000,"author":"XXL","alarmEmail":"","executorRouteStrategy":"FIRST","executorHandler":"firstJobHandler","executorParam":"123","executorBlockStrategy":"SERIAL_EXECUTION","executorTimeout":100,"executorFailRetryCount":0,"glueType":"BEAN","glueSource":"","glueRemark":"GLUE代码初始化","glueUpdatetime":1561538414000,"childJobId":"","jobStatus":"NONE"},{"id":2,"jobGroup":2,"jobCron":"0/1 * * * * ? ","jobDesc":"测试任务1","addTime":1561532680000,"updateTime":1561612757000,"author":"XXL","alarmEmail":"","executorRouteStrategy":"FIRST","executorHandler":"demoJobHandler","executorParam":"123","executorBlockStrategy":"SERIAL_EXECUTION","executorTimeout":101,"executorFailRetryCount":1,"glueType":"BEAN","glueSource":"","glueRemark":"GLUE代码初始化","glueUpdatetime":1561532680000,"childJobId":"","jobStatus":"NONE"}],"recordsTotal":4}
}
/**
* 增加定时任务配置
*/
@Test
public void addInfo(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("jobGroup","1"); //执行器主键id
map.add("jobCron","0/1 * * * * ? "); //表达式
map.add("jobDesc","测试任务我是最新的测试任务啊啊啊啊啊啊"); //任务描述
map.add("author","zhanglei"); //负责人
map.add("alarmEmail","[email protected]"); //报警邮件
map.add("executorRouteStrategy","FIRST"); //执行器路由策略
map.add("executorHandler","测试JobHandler"); //执行器,任务Handler名称
map.add("executorParam","121454"); //执行器,任务参数
map.add("executorBlockStrategy","SERIAL_EXECUTION"); //阻塞处理策略
map.add("executorTimeout","101"); //任务执行超时时间,单位秒
map.add("executorFailRetryCount","1"); //失败重试次数
map.add("glueType","BEAN"); //GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
map.add("glueSource",""); //GLUE源代码
map.add("glueRemark","GLUE代码初始化"); //GLUE备注
map.add("childJobId",""); //子任务ID,多个逗号分隔
// map.add("jobStatus",""); //任务状态 【base on quartz】
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/add", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":"15"}
}
/**
* 修改定时任务配置
*/
@Test
public void updateInfo(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","14"); //注意:修改必须带主键
map.add("jobGroup","1"); //执行器主键id
map.add("jobCron","0/1 * * * * ? "); //表达式
map.add("jobDesc","测试任务我是最新的测试任务啊啊啊啊啊啊"); //任务描述
map.add("author","zhanglei"); //负责人
map.add("alarmEmail","[email protected]"); //报警邮件
map.add("executorRouteStrategy","FIRST"); //执行器路由策略
map.add("executorHandler","测试JobHandler"); //执行器,任务Handler名称
map.add("executorParam","121454"); //执行器,任务参数
map.add("executorBlockStrategy","SERIAL_EXECUTION"); //阻塞处理策略
map.add("executorTimeout","101"); //任务执行超时时间,单位秒
map.add("executorFailRetryCount","1"); //失败重试次数
map.add("glueType","BEAN"); //GLUE类型 #com.xxl.job.core.glue.GlueTypeEnum
map.add("glueSource",""); //GLUE源代码
map.add("glueRemark","GLUE代码初始化"); //GLUE备注
map.add("childJobId",""); //子任务ID,多个逗号分隔
// map.add("jobStatus",""); //任务状态 【base on quartz】
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/update", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/**
* 删除定时任务配置
*/
@Test
public void removeInfo(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","15"); //注意:删除必须带主键
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/remove", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/**
* 启动定时任务
*/
@Test
public void startInfo(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","13"); //启动的任务id
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/start", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/**
* 停止定时任务
*/
@Test
public void stopInfo(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","13"); //启动的任务id
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/stop", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
/**
* 执行一次定时任务
*/
@Test
public void startOne(){
HttpHeaders headers = new HttpHeaders();
List<String> cookies = new ArrayList<>();
/* 登录获取Cookie 这里是直接给Cookie,可使用下方的login方法拿到Cookie给入*/
cookies.add("XXL_JOB_LOGIN_IDENTITY=6333303830376536353837616465323835626137616465396638383162336437; Path=/; HttpOnly");
headers.put(HttpHeaders.COOKIE,cookies);
MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
map.add("id","13"); //启动的任务id
map.add("executorParam","13"); //启动的任务参数
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
ResponseEntity<String> response = restTemplate.postForEntity("http://localhost:8888/xxl-job-admin/jobinfo/trigger", request, String.class);
System.out.println(response.getBody()); //{"code":200,"msg":null,"content":null}
}
}
作者在XXL-JOB官方文档的TODO LIST中已经将任务权限管理功能提上日程,后续版本将会越来越完美!