参考: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}
} }

xxl-job初学转载,不断更新的更多相关文章

  1. (转载)更新到Retrofit2的一些技巧

    更新到Retrofit2的一些技巧 作者 小武站台 关注 2016.02.22 22:13* 字数 1348 阅读 1621评论 0喜欢 5赞赏 1 原文链接:Tips on updating to ...

  2. Selenium2Library使用Remote功能(转载并更新)

    在selenium2library库的open browser中,除了我们常用的url,browser外,还有几个不常用的参数.如:remote_url的用法 1.下载selenium-server- ...

  3. [转载]linux 更新yum源 改成阿里云源

    原文链接:https://www.cnblogs.com/bincoding/p/7892762.html 1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc ...

  4. [更新] Jetbrains IntelliJ IDEA 2019 的许可证密钥

    亲测有效.转载目的:提供一种方法,当然可以看一下原网站的更新及其他方法.转载:[更新] Jetbrains IntelliJ IDEA 2019 的许可证密钥(100%工作),By Gideon    ...

  5. “21天教你学会C++”

    下面是一个<Teach Yourself  C++ in 21 Days>的流程图,请各位程序员同仁认真领会.如果有必要,你可以查看这个图书以作参照:http://www.china-pu ...

  6. 干货!一篇文章集合所有Linux基础命令,适合所有菜鸟学习和老手回顾!

    1 文件{ ls -rtl # 按时间倒叙列出所有目录和文件 ll -rt touch file # 创建空白文件 rm -rf 目录名 # 不提示删除非空目录(-r:递归删除 -f强制) dos2u ...

  7. 【转载】Arcengine效率探究之二——属性的更新

    文转载自hymyjl2010<Arcengine效率探究之二——属性的更新>   修改一批要素的属性有多种方法,当数据量较大时,若选择不当可能会大大影响速度. 一.IRowBuffer 方 ...

  8. 转载:第五弹!全球首个微信小程序(应用号)开发教程!通宵吐血赶稿,每日更新!

    博卡君今天继续更新,忙了一天,终于有时间开工写教程.不罗嗦了,今天我们来看看如何实现一些前端的功能和效果. 第八章:微信小程序分组开发与左滑功能实现 先来看看今天的整体思路: 进入分组管理页面--&g ...

  9. 转载:第四弹!全球首个微信小程序(应用号)开发教程!通宵吐血赶稿,每日更新!

    感谢大家支持!博卡君周末休息了两天,今天又回到战斗状态了.上周五晚上微信放出官方工具和教程了,推荐程序猿小伙伴们都去试一试,结合教程和代码,写写自己的 demo 也不错. 闲话不多说,开始更新! 第七 ...

  10. 转载:第三弹!全球首个微信小程序(应用号)开发教程!通宵吐血赶稿,每日更新!

    感谢朋友们的支持!这两天博卡君收到了很多支持和安慰,也认识了很多志同道合的朋友.目前微信公布的工具和代码都不是正式版,随时有可能调整,大家先体验和学习为主吧.最近这个教程搞得我也心力交瘁了,虽然苦逼, ...

随机推荐

  1. 统信UOS系统开发笔记(三):从Qt源码编译安装之编译安装Qt5.12.8

    前言   上一篇,是使用Qt提供的安装包安装的,有些场景需要使用到自己编译的Qt,所以本篇如何在统信UOS系统上编译Qt5.12.8源码.   统信UOS系统版本   系统版本:   Qt源码下载   ...

  2. error: #20: identifier "arm_cfft_instance_f64" is undefined

    在使用Keil5的过程中,偶尔遇到这个问题,以及类似的问题,报错的数量大概200多个. error type>(42): error: #20: identifier "arm_cff ...

  3. STL-array(ACM)

    1.C++ 11 出现的, C++98没有 2.可以作为数组元素 pair<array<int, 3>, int>pair<int a[3], int > 不能这样 ...

  4. Vue项目学习

    一.二维数组尝试 var vm = new Vue({ el: "#app", data: { huilv:[ [6.8540, 132.9787, 1298.7013, 1.32 ...

  5. .Net7发现System.Numerics.Vector矢量化的一个bug,Issues给了dotnet团队

    因为前几天做.Net7的矢量化性能优化,发现了一个bug.在类System.Numerics.Vector里面的成员变量IsHardwareAccelerated.但是实际上不确定这个bug是visu ...

  6. 蔬菜识别系统Python+TensorFlow+Django+卷积神经网络算法

    一.介绍 蔬菜识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法.并通过对数据集进行训练,最后得到一个识别精度较高的模型.并基于Django框架,开 ...

  7. RLHF技术在智能娱乐中的应用:提高娱乐智能化和自动化水平”

    目录 随着人工智能技术的不断发展,智能娱乐成为了人们越来越关注的话题.在智能娱乐领域中,RLHF技术的应用正在逐渐显现.本文将介绍RLHF技术在智能娱乐中的应用,提高娱乐智能化和自动化水平. 首先,我 ...

  8. React后台管理系统07 首页布局

    注释掉App.tsx中的几个路由组件: 将Home.tsx中的代码使用ant Design网站中的布局进行替换 复制的代码如下: import { DesktopOutlined, FileOutli ...

  9. P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解

    P7561[JOISC 2021 Day2] 道路の建設案 (Road Construction) 题解 题目描述 JOI 国是一个 \(x\times y\) 的二维平面,王国里有 \(n\) 个城 ...

  10. P3047 [USACO12FEB]Nearby Cows G 题解

    P3047 [USACO12FEB]Nearby Cows G 题目描述 思路 使用换根DP, 设 \(dp[i][j]\) 表示以 \(i\) 为根节点的子树中深度小于等于 \(j\) 的点的权值之 ...