参考资料:
因最近,博主使用到分布式定时任务功能,所以将学习的过程记录下来
1 传统的定时任务存在的问题
在传统的SSM项目中,常使用Quartz定时任务框架;在一般的SpringBoot项目中,可使用@Schedule
注解实现定时任务功能.
上述功能,在单机环境下, 会出现一些问题.如什么时候可以手动触发一次? 想更换定时任务时间?没有容错机制,时间到了定时任务没有跑,怎么补救? 定时任务的运行日志查看等等?
如果是在集群环境下,上述功能,就会出现很多问题. 虽然可以通过人为配置文件,去管理控制,但也仅仅限于小项目,几台机器的集群,与此同时,这也给维护添加了很多困难.而且还没有彻底解决上面一系列问题.
2 xxl-job简介
xxl-job: 作为分布式任务调度系统,主要为了实现高可用、容错管理、负载均衡、管理机制等功能. 而且该学习成本低,使用简单,拿来即用.
3 xxl-job的简单使用
1 从码云上克隆代码
2 修改数据库连接
文件在目录: /xxl-job/xxl-job-admin/src/main/resources/application.properties
3 执行数据库初始sql脚本
文件在目录: /xxl-job/doc/db/tables_xxl_job.sql
4 运行xxl-job-admin模块中的XxlJobAdminApplication,启动项目
访问地址: http://localhost:8080/xxl-job-admin
用户名/密码: admin/123456
4 任务调度中心说明
1 运行报表
该tag页,主要统计定时任务的信息.包括,任务数量,调度次数,执行器数量.成功失败的比率,调度时间等图表.
2 任务管理
定时任务的管理,包括,新增,编辑,删除,查询等基础功能, 还提供停止,关闭,执行一次定时任务等功能.
3 调度日志
定时任务的执行日志,包括成功和失败,可以查看具体的失败原因.
4 执行器管理
执行器AppName: 包括执行器新增,编辑,删除,查询等功能,执行器,主要是供任务调度时使用,简单来说,作为定时任务的载体,保存机器的地址等信息.
新增执行器说明:
AppName : 每个执行器集群的唯一标示AppName, 执行器会周期性以AppName为对象进行自动注册,可通过该配置自动发现注册成功的执行器, 供任务调度时使用.
名称 : 随意填写,可以描述该机器名具体的功能的,主要是因AppName大多由字母和数字组成,确保唯一性,所以需要名称来描述来描述其功能性.
自动注册 : 执行器自动进行执行器注册,调度中心通过底层注册表可以动态发现执行器机器地址.
手动注册 : 人工手动录入执行器的地址信息,多地址逗号分隔,供调度中心调用.
机器地址 : 人工录入执行器时有效,多个地址逗号分隔.
5 用户管理
任务调度中心用户的新增,编辑,删除,查询,以及权限的管理等.
6 使用教程
xxl-job分布式任务调度中心的使用文档.
5 自定义定时任务
按照给的Demo案列,我们自定义定时任务.
1 创建一个模块,引入maven依赖
<!-- 规定jar包版本 -->
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot (依赖管理:继承一些默认的依赖,工程需要依赖的jar包的管理,申明其他dependency的时候就不需要version) -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 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>
</dependency>
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
</dependencies>
2 创建配置文件application.properties
# 1 修改server.port端口号,不要和之前模块重复
# 2 修改xxl.job.executor.appname的名称,最好不要重复
# 3 修改xxl.job.executor.port端口号,不要重复
# web port
server.port=8082
# 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.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-springboot2
### 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=9998
### 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
3 创建XxlJobConfig配置类
@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;
}
}
4 创建定时任务
@Component
public class SampleXxlJob {
private static Logger logger = LoggerFactory.getLogger(SampleXxlJob.class);
@XxlJob("customJobHandler")
public void customJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
System.out.println("============我是自定义定时任务2=========");
}
}
5 创建启动类
@SpringBootApplication
public class XxlJobExecutorApplication {
public static void main(String[] args) {
SpringApplication.run(XxlJobExecutorApplication.class, args);
}
}
整个项目目录结构如下:
6 启动项目,任务调度中心添加执行器
7 添加定时任务
8 开启定时任务,查看运行结果
6 集群中xxl-job的使用
1 执行器配置修改,添加集群的地址,多个用逗号隔开
2 添加定时任务
注意将路由策略修改, 为了查看效果,我们选择轮询,即每个机器上的定时任务轮流触发.
3 开启定时任务,查看效果
7 总结
xxl-job,作为一个开源的,简单上手的,开箱即用的分布式任务调度,非常容易使用和维护.最初,没使用过时,以为晦涩难懂,跟着官方文档和博客学习下来,收货颇多,也明白了,所有的东西,不去尝试,仅仅停留在观看的层面,永远都很难.