Docker部署XXL-JOB并整合Spring Boot
在最近开发过程当中有一个需求,将Redis里面的数据定时存储到Mysql里面,虽然Spring Boot 当中提供了一个 @Scheduled
注解可以实现定时任务,但是它存在一些缺点
- 单机调度:
@Scheduled
是单机调度,不适合分布式环境下的任务调度,无法实现任务的分布式部署和调度。 - 依赖于应用运行:
@Scheduled
需要依赖于应用的运行,如果应用停止或重启,定时任务也会受到影响。、 - 不能够对任务进行灵活的动态化管理,例如任务的添加、删除、暂停、恢复等操作
最后采用分布式任务调度平台XXL-JOB实现定时任务,XXL-JOB有以下一些优点
- 分布式支持:xxl-job 是一个分布式任务调度平台,支持分布式部署和调度,可以实现任务的高可用和高并发。
- 任务管理:提供了任务的添加、删除、暂停、恢复等管理功能,便于任务的维护和管理。
- 失败重试:xxl-job 支持失败重试机制,可以自动重试失败的任务,保证任务的可靠性。
1 XXL-JOB架构介绍
XXL-JOB 是一个分布式任务调度平台,它由调度中心(Admin)、执行器(Executor)和数据库组成
- 调度中心是 XXL-JOB 的管理端,它是任务的调度控制中心。调度中心负责任务的添加、删除、暂停、恢复等管理操作,为官方提供
- 执行器是 XXL-JOB 的执行端,它是任务的实际执行者。执行器从调度中心获取待执行的任务,然后按照指定的调度策略和触发方式,在指定时间点或时间间隔内执行任务逻辑
- 数据库用于存储任务的元数据和调度信息。调度中心和执行器都需要访问数据库来获取任务信息、执行日志等。是调度中心和执行器共享的数据
2 调度中心配置
2.1 初始化数据库
下载官方项目源码并解压,获取 “调度数据库初始化SQL脚本” 并执行即可。
“调度数据库初始化SQL脚本” 位置为:
/xxl-job/doc/db/tables_xxl_job.sql
调度中心支持集群部署,集群情况下各节点务必连接同一个mysql实例
如果mysql做主从,调度中心集群节点务必强制走主库
2.2 利用 Dokcer 搭建调度中心
- 拉取 Docker 镜像
docker pull xuxueli/xxl-job-admin:2.3.1
- 创建 Docker 容器并运行,需要配置数据库的 IP 端口以及账号密码
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123456" -p 8848:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:2.3.1
- 输入 http://ip:port/xxl-job-admin 进入调度中心,初始密码为root 123456
3 执行器配置
- 引入 maven 依赖
<!-- xxl-job-core -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
- 编写配置文件
xxl:
job:
# 执行器通讯TOKEN [选填]:非空时启用;
accessToken: default_token
admin:
# 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
address: http://192.168.152.101:8848/xxl-job-admin
executor:
# 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
appName: xxxxxx
# 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
# 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 1314
# 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logPath:
# 执行器日志保存天数 [选填] :值大于3时生效,启用执行器Log文件定期清理功能,否则不生效;
logRetentionDays: -1
- 执行器组件配置,将执行器交给 Spring 容器管理
package com.****.system.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
@Slf4j
@Data
@Component
@Configuration
public class XxlJobConfig {
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.admin.address}")
private String adminAddress;
@Value("${xxl.job.executor.appName}")
private String executorAppName;
@Value("${xxl.job.executor.ip}")
private String executorIp;
@Value("${xxl.job.executor.port}")
private Integer executorPort;
@Value("${xxl.job.executor.logPath}")
private String executorLogPath;
@Value("${xxl.job.executor.logRetentionDays}")
private Integer executorLogRetentionDays;
// 确保 xxl-job 组件在应用启动时自动连接到调度中心并开始执行任务,在应用关闭时自动停止任务执行器并释放相关资源
@Bean(initMethod = "start", destroyMethod = "destroy")
public XxlJobSpringExecutor xxlJobExecutor() {
log.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddress);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setAppname(executorAppName);
xxlJobSpringExecutor.setIp(executorIp);
xxlJobSpringExecutor.setPort(executorPort);
xxlJobSpringExecutor.setLogPath(executorLogPath);
xxlJobSpringExecutor.setLogRetentionDays(executorLogRetentionDays);
return xxlJobSpringExecutor;
}
}
启动项目,观察 Spring Boot 日志,成功连接 XXL-JOB
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s9gwb2Yd-1689920270266)(C:\Users\91445\AppData\Roaming\Typora\typora-user-images\image-20230721133435907.png)]
4 运行测试
4.1 调度中心执行器连接
添加执行器
配置成功展示
4.2 GLUE模式(Java)
GLUE运行模式的任务实际上是一段继承自IJobHandler的Java类代码,它在执行器项目中运行,可使用@AutoWired
和 @Resource
注入执行器里中的其他服务
- 创建 GLUE 任务
- 编写代码
package com.xxl.job.service.handler;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.IJobHandler;
public class DemoGlueJobHandler extends IJobHandler {
@Override
public void execute() throws Exception {
System.out.println("GLUE XXL-JOB ==========\n");
}
}
- 调度一次
4.3 BEAN模式(方法形式)
该模式可以 Spring 容器内的方法交给 XXL-JOB 管理调度,具体实现如下
- 在执行器项目当中,编写方法,加上
@XxlJob
注解
package com.****.system.service.impl;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.****.system.service.TaskService;
import org.springframework.stereotype.Service;
@Service
public class TaskServiceImpl implements TaskService {
@XxlJob(value = "testBean")
public void testBean() {
System.out.println("bean XXL-JOB ======");
}
}
- 在调度中心增加任务
- 启动项目
控制台输出成功注册日志
成功自动调用方法