xxl-job初学转载,不断更新
参考:https://blog.csdn.net/xhmico/article/details/122324950
官网与源码下载地址
官网:https://www.xuxueli.com/xxl-job/
源码下载地址:https://github.com/xuxueli/xxl-job/releases
准备工作
1.下载源码
根据上面提供的 源码下载地址 链接进去下载源码就完事
windows 下使用下载这个就行了
下载源码之后解压
2.IDEA导入项目
导入之后是这样的
可以看到作者提供的源码里面主要分了三个模块
xxl-job-admin
xxl-job-core
xxl-job-executor-samples
我们先看看 xxl-job-admin 这个模块
在启动这个模块之前先要做数据的准备工作
3.数据准备
先将所需要的表准备好,这里直接用作者提供的 sql 就行
复制 sql ,到你自己的数据库中执行
修改配置文件
这里改成你自己数据库的配置(你可以看看其它的配置信息,里面也有修改发送邮件等配置)
4.登陆任务调度中心
运行 xxl-job-admin 的启动类
启动完成后就可以登陆上去看看
地址:http://localhost:8080/xxl-job-admin
进去是这样子的,但是需要账号跟密码
密码是通过md5加密而来的,真实的账号:admin 密码:123456
登陆之后就能看任务调度中心的控制页面了
5.测试定时任务
这里作者提供了 xxl-job 整合其它框架或者软件,这里我们先学习整合 spring-boot 的来,毕竟这个对于 java 开发是最重要的
可以看到整合了 spring-boot 的这个项目中的 pom 文件里是有引入这个 xxl-job-core 的依赖的
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
所以在我们自己的项目中如果到时候要用这个定时器,也需要加入这个依赖
作者这里也提供了 docker 的配置,需要在自己服务器上运行的可以使用
再来看看这个项目的配置文件
# web port
server.port=8081
# no web
#spring.main.web-environment=false
# log config
logging.config=classpath:logback.xml
### xxl-job admin address list, such as "http://address" or "http://address01,http://address02"
# 这里主要是配置你任务调度中心的地址(就是控制平台的),也就是xxl-job-admin的地址,如果你是本地起的就不需要改了,否则改成你服务器上的地址
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=${server.port}
#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
说明:
addresses: 任务调度中心部署根地址(必填)
appname:这个名称可以自己定义,但一般为项目名称-job,此名称用于在任务调度中心中,配置执行器时的名称标识
ip:执行器ip,可以不填,会自动识别注册
porrt:执行器端口号
logpath:执行器运行日志文件存储磁盘路径
logrententiondays:执行器日志保存天数,值大于3时生效,启用执行器log文件定期清理功能,否则不生效
AccessToken:执行器通讯token,非空时启用
在看看配置类
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@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;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
修改执行器端口偏移(这个看你自己的喜好,你可以自己去指定端口,我是直接拿服务的端口加上1000而的来执行器端口的)
直接运行下这个 xxl-job-executor-sample-spring 服务的启动类
启动之后去 任务调度中心 的 执行器管理 就能看到自动注入的执行器了,端口是9081,非常的 nice
再来回过头看看 任务调度中心 的 任务管理 ,之前我想大家都有看到这里有个默认的定时任务吧
这个定时任务其实就是 xxl-job-executor-sample-springboot 中的任务,可以在 SampleXxlJob.java 类中找到
那就来执行下这个定时器任务呗
再看看这个测试任务1 ,它的 cron 表达式是这样的0 0 0 * * ? *
可以看到这个是每天凌晨 0 点执行,这可不成,那就改一改吧
在右侧 操作 - 编辑 可修改定时规则
再去修改下这个项目的 demoJobHandler 定时任务,给它打印点东西,便于观察
重启该项目,清空控制台
启动下该定时任务
在右侧 操作 - 启动 启动该定时任务
到点了,就去控制台看看执行情况
可以看到控制台有六次打印(因为设置的就是 11:35 开始每 10 秒 执行一次)
也可以去查询这个定时任务的日志
2.整合到自己的项目中
现在对于怎么使用这个 xxl-job 应该都差不多了吧,现在我就把它整合到自己的项目中去,新建springboot项目
(以下内容需要根据项目自身的情况去配置,仅供参考)
pom.xml
<?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>
<artifactId>mike-parent</artifactId>
<groupId>com.mike</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mike-xxl-job</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- 我的公共模块 -->
<dependency>
<groupId>com.mike</groupId>
<artifactId>mike-common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- nacos 服务发现 -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- spring-boot-starter-web (spring-webmvc + tomcat) -->
<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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<outputDirectory>${project.parent.basedir}/jars</outputDirectory>
<finalName>${project.artifactId}</finalName>
<!-- 指定该Main Class为全局的唯一入口 -->
<mainClass>com.mike.mo.job.XxlJobApplication</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal><!--可以把依赖的包都打包到生成的Jar包中-->
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
application.yml
server:
port: 6804
logging:
config: classpath:logback.xml
file: /www/mike/project-mike/logs/mike-xxl-job.log
level:
com.alibaba.nacos: error
spring:
application:
name: mike-xxl-job
main:
allow-bean-definition-overriding: true
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: f90ad91c-ac39-4a2d-8fb3-fcd33ded9123
datasource:
url: jdbc:mysql://127.0.0.1:3306/duojiala?characterEncoding=UTF-8&useSSL=false&serverTimezone=GMT%2B8
hikari:
username: 'root'
password: 'root'
driver-class-name: 'com.mysql.cj.jdbc.Driver'
max-lifetime: 120000
xxl-job:
admin:
addresses: http://127.0.0.1:8080/xxl-job-admin
executor:
appName: mike-xxl-job
ip:
port: ${server.port}
logPath: /data/applogs/xxl-job/jobhandler
logRetentionDays: 30
accessToken:
logback.xml (这个是直接复制作者的,我也没研究过),也粘在下面
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logback</contextName>
<property name="log.path" value="/data/applogs/xxl-job/xxl-job-executor-sample-springboot.log"/>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="console"/>
<appender-ref ref="file"/>
</root>
</configuration>
MikeXxlJob.java
@Component
public class MikeXxlJob {
private final static Logger logger = LoggerFactory.getLogger(MikeXxlJob.class);
/**
* 我的第一个定时器任务
*/
@XxlJob("funJobHandler")
public void funJobHandler() {
System.out.println("啊~我执行了~~~~");
}
}
我将 xxl-job 的配置整合成一个bean对象,跟之前的 properties 配置文件方式有点不太一样
XxlJobBeanConfig.java
@Component
@ConfigurationProperties(prefix = "xxl-job")
@Data
public class XxlJobBeanConfig {
private Admin admin;
private Executor executor;
private String accessToken;
@Data
public static class Executor {
private String appName;
private String ip;
private int port;
private String logPath;
private int logRetentionDays;
}
@Data
public static class Admin {
private String addresses;
}
}
XxlJobConfig.java xxl-job 定时器配置类
@Configuration
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class XxlJobConfig {
private final Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
private final XxlJobBeanConfig bean;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(bean.getAdmin().getAddresses());
xxlJobSpringExecutor.setAppname(bean.getExecutor().getAppName());
xxlJobSpringExecutor.setAddress(bean.getAdmin().getAddresses());
xxlJobSpringExecutor.setIp(bean.getExecutor().getIp());
xxlJobSpringExecutor.setPort(bean.getExecutor().getPort()+1000); //端口向后偏移1000
xxlJobSpringExecutor.setAccessToken(bean.getAccessToken());
xxlJobSpringExecutor.setLogPath(bean.getExecutor().getLogPath());
xxlJobSpringExecutor.setLogRetentionDays(bean.getExecutor().getLogRetentionDays());
return xxlJobSpringExecutor;
}
}
以上就是我这个定时器模块的全部代码了,现在就来运行下启动类
回到 任务调度中心 - 执行器管理 ,刷新好像也没看到刚刚启动的服务也没有注册到这个管理当中,那就自己 新增 吧
注意:这里的机器地址是yml中执行器的地址,也就是本项目的地址,端口号为设定的端口号,后谜案要加/
去 任务管理 新增定时任务
设置好定时规则,启动新增的这个定时任务
时间到点,我的定时任务也执行了
查看下调度日志
进一步学习
*(1)yml文件说明
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天,否则功能不生效。
*(2)新增执行器时,需要填写的信息说明
- AppName:这是用来唯一标识每个执行器集群的应用名称,执行器会周期性地以AppName为参数进行自动注册。可通过该配置自动发现注册成功的执行器,供任务调度时使用。
- 名称:执行器的名称,因为AppName限制字母数字等组成,可读性不强,名称可以提高执行器的可读性。
- 排序:执行器的排序,系统中需要执行器的地方,如任务新增,将会按照该排序读取可用的执行器列表。
- 注册方式:调度中心获取执行器地址的方式,有以下两种:
- 自动注册:执行器自动进行执行器注册,调度中心通过底层注册表可以动态发现执行器机器地址。
- 手动录入:人工手动录入执行器的地址信息,多地址逗号分隔,供调度中心使用。
- 机器地址:只有在“注册方式”为“手动录入”时可编辑,支持人工维护执行器的地址信息。
注意:AppName的取值和示例工程的application.properties文件中的xxl.job.executor.appname字段的取值相同,注册方式选择自动注册。新增完成之后,就可以在执行器列表中看到新建的执行器, 而我在写入的时候将applcation.properties替换为了bootstrap.yml,但内容不变;
*(3) 新增任务时,需要填写的信息说明 - 执行器:任务绑定的执行器,任务触发调度时将会自动发现注册成功的执行器,实现任务自动发现功能;另一方面,也可以方便地进行任务分组。每个任务必须绑定一个执行器,可以在“执行器管理”页面进行设置。
- 任务描述:任务的描述信息,便于任务管理。
- 路由策略:当执行器集群部署时,提供丰富的路由策略,包括:
FIRST(第一个):固定选择第一个机器。
LAST(最后一个):固定选择最后一个机器。
ROUND(轮询):轮流选择每台机器。
RANDOM(随机):随机选择在线的机器。
CONSISTENT_HASH(一致性HASH):每个任务按照Hash算法固定选择某一台机器,且所有任务均匀散列在不同机器上。
LEAST_FREQUENTLY_USED(最不经常使用):使用频率最低的机器优先被选举。
LEAST_RECENTLY_USED(最近最久未使用):最久为使用的机器优先被选举。
FAILOVER(故障转移):按照顺序依次进行心跳检测,第一个心跳检测成功的机器选定为目标执行器并发起调度。
BUSYOVER(忙碌转移):按照顺序依次进行空闲检测,第一个空闲检测成功的机器选定为目标执行器并发起调度。
SHARDING_BROADCAST(分片广播):广播触发对应集群中所有机器执行一次任务,同时传递分片参数;可根据分片参数开发分片任务。 - Cron:触发任务执行的Cron表达式,具体可百度。
- 运行模式:
BEAN模式:任务以JobHandler的方式维护在执行器端;需要结合 “JobHandler”属性匹配执行器中的任务;
GLUE模式(Java):任务以源码方式维护在调度中心;该模式的任务实际上是一段继承自IJobHandler的Java类代码并以“groovy”源码的方式维护,它在执行器项目中运行,可使用@Resource/@Autowire注入执行器里中的其他服务;
GLUE模式(Shell):任务以源码方式维护在调度中心;该模式的任务实际上是一段“shell”脚本;
GLUE模式(Python):任务以源码方式维护在调度中心;该模式的任务实际上是一段“python”脚本;
GLUE模式(NodeJS):任务以源码方式维护在调度中心;该模式的任务实际上是一段“nodejs”脚本; - JobHandler:
只有在运行模式为“BEAN模式”时生效,对应执行器中新开发的JobHandler类的“@JobHandler”注解自定义的value值。 - 子任务:
每个任务都拥有一个唯一的任务ID(任务ID可以从任务列表获取),当本任务执行结束并且执行成功时,将会触发子任务ID所对应的任务的一次主动调度。 - 阻塞处理策略:调度过于密集,执行器来不及处理时的处理策略:
失败告警(默认):调度失败和执行失败时,都将会触发失败报警,默认会发送报警邮件。
失败重试:调度失败时,除了进行失败告警之外,将会自动重试一次;注意在执行失败时不会重试,而是根据回调返回值判断是否重试。 - 任务参数:任务执行所需的参数,多个参数时用逗号分隔,任务执行时将会把多个参数转换成数组传入。
- 报警邮件:任务调度失败时邮件通知的邮箱地址,支持配置多邮箱地址,配置多个邮箱地址时用逗号分隔。
- 负责人:任务的负责人。
*(4)BEAN模式:
任务逻辑以JobHandler的形式存在于“执行器”所在项目中,如我们刚刚所演示的Hello,World 的入门案例
上述代码有三点需要注意:
必须使用XXL-JOB的@JobHandler注解(第1行),指定JobHandler的名称为“demoJobHandler”,在调度中心新建任务的JobHandler字段的取值要与此相同。
必须继承IJobHandler抽象类(第3行),并且实现它的execute()方法,这是实现任务逻辑的方法。
IJobHandler抽象类还有init()方法和destroy()方法,这两个方法是空方法,在任务实例初始化和销毁时调用,任务实现类可以选择性地覆盖这两个方法。
*(5)GLUE(Java)模式任务,
任务以源码方式维护在调度中心,支持通过Web IDE在线更新,实时编译和生效,因此不需要指定JobHandler。开发流程如下:
Step-1 新建调度任务
参考上文“任务调度属性”对新建的任务进行参数配置,运行模式选择“GLUE模式(Java)”,如下图所示:
Step-2 开发任务代码
在任务列表中选中指定的GLUE(Java)任务,点击该任务右侧的“GLUE”按钮,将会前往GLUE任务的Web IDE界面,在该界面支持对任务代码进行开发(也可以在IDE中开发完成后,复制粘贴到编辑中)。
版本回溯功能:在GLUE任务的Web IDE界面,选择右上角下拉框“版本回溯”,会列出该GLUE任务的更新历史(支持30个版本的版本回溯),选择相应版本即可显示该版本代码,保存后GLUE代码即回退到对应的历史版本。GLUE任务代码和Web IDE界面,如下图所示:
*(5)分片广播任务
执行器集群部署时,任务路由策略选择“分片广播”的情况下,一次任务调度将会广播触发对应集群中所有执行器执行一次任务,同时传递分片参数,可以根据分片参数开发分片任务。
“分片广播”以执行器为维度进行分片,支持动态扩容执行器集群从而动态增加分片数量,协同进行业务处理;在进行大数据量业务操作时可显著提升任务处理能力和速度。
“分片广播”和普通任务开发流程一致,不同之处在于可以获取分片参数,通过分片参数进行分片业务处理。开发流程如下:
Step-1 开发JobHandler代码
在示例工程的com.example.demo.jobhandler包中,新建ShardingJobHandler任务类,关键代码如下所示:
@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行获取分片参数的两个属性:
shardingVO.getIndex() 当前分片序号(从0开始),执行器集群列表中当前执行器的序号。
shardingVO.getTotal() 总分片数,执行器集群的总机器数量。
Step-2 新建调度任务
参考上文“任务调度属性”对新建的任务进行参数配置,运行模式选择“BEAN模式”,路由策略选择“分片广播”,JobHandler属性填写任务注解@JobHandler中定义的值,如下图所示:
分片广播的路由策略不仅适用于BEAN运行模式,而且也适用于GLUE(Java)运行模式。这项功能适用于以下业务场景:
分片任务场景
10个执行器的集群来处理10w条数据,每台机器只需要处理1w条数据,耗时降低10倍。
广播任务场景
广播执行器机器运行shell脚本、广播集群节点进行缓存更新等
远程调用XXL-JOB
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":"1326209681@qq.com","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","1326209681@qq.com"); //报警邮件
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","1326209681@qq.com"); //报警邮件
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}
}
}
本文作者:spiderMan1-1
本文链接:https://www.cnblogs.com/cgy1995/p/17422156.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?