xxl-job 设计分两个模块,调度模块,执行模块
调度模块(调度中心):负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码;
执行模块(执行器):负责接收调度请求并执行任务逻辑;
Spring Boot 集成 XXL-JOB 主要分为以下两步:
- 部署调度中心(xxl-job-admin)
- 配置执行器
下载xxl-job的源码,这里用的版本是:2.3.1
git clone https://github.com/xuxueli/xxl-job.git
目录结构如下:
xxl-job
|__doc
|__tables_xxl_job.sql 调度中心数据库脚本
|__xxl-job-admin 调度中心源码
|__xxl-job-core 公共依赖源码
|__xxl-job-executor-samples 执行器Sample示例
|__xxl-job-executor-sample-frameless Springboot版本,可直接使用或者将此模块与业务代码整合
|__xxl-job-executor-sample-springboot
1、部署调度中心(xxl-job-admin)
调度中心:个人理解为服务端,提供定时任务服务调度;
部署方式有2种
- Docker 镜像方式部署(推荐);
- 将下载的源码xxl-job-admin打个jar包,然后直接命令运行;
(1)初始化调度中心数据库:
新建名为数据库 xxl_job 的数据库,并运行数据库脚本tables_xxl_job.sql
(2)下载镜像,跑起调度中心服务:
- 如需自定义 mysql 等配置,可通过 “-e PARAMS” 指定,参数格式 PARAMS=“–key=value --key2=value2”
- 配置项参考文件:xxl-job/xxl-job-admin/src/main/resources/application.properties
### 调度中心JDBC链接:链接地址请保持和 2.1章节 所创建的调度数据库的地址一致
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=root_pwd
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
### 报警邮箱
spring.mail.host=smtp.qq.com
spring.mail.port=25
[email protected]
spring.mail.password=xxx
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory
### 调度中心通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 调度中心国际化配置 [必填]: 默认为 "zh_CN"/中文简体, 可选范围为 "zh_CN"/中文简体, "zh_TC"/中文繁体 and "en"/英文;
xxl.job.i18n=zh_CN
## 调度线程池最大线程配置【必填】
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100
### 调度中心日志表数据保存天数 [必填]:过期日志自动清理;限制大于等于7时生效,否则, 如-1,关闭自动清理功能;
xxl.job.logretentiondays=30
- 如需自定义 JVM内存参数 等配置,可通过 “-e JAVA_OPTS” 指定,参数格式 JAVA_OPTS=“-Xmx512m”
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://192.168.207.39:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123456 --xxl.job.logretentiondays=8" -p 8080:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:2.3.1
我们把调度中心xxl-job-admin部署到k8s上
下载好要用到的镜像:
docker pull xuxueli/xxl-job-admin:2.3.1
xxl-job-admin-deploy.yaml文件编写:
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: cdhy
name: xxl-job-admin-deployment
spec:
replicas: 1
selector:
matchLabels:
prod: xxl-job-admin-pod
template:
metadata:
labels:
prod: xxl-job-admin-pod
spec:
containers:
- name: xxl-job-admin
image: xuxueli/xxl-job-admin:2.3.1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: PARAMS # 定义变量,用来接收sql的用户/密码
value: "--spring.datasource.url=jdbc:mysql://192.168.207.39:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123456 --xxl.job.logretentiondays=8"
---
apiVersion: v1
kind: Service
metadata:
namespace: cdhy
name: xxl-job-admin-service
spec:
type: NodePort
ports:
- name: xxl-job-admin
port: 8080
nodePort: 30080
selector:
prod: xxl-job-admin-pod
执行yaml文件:
kubectl apply -f xxl-job-admin-deploy.yaml
访问管理后台 (30080是service暴露出来的端口)
192.168.202.63:30080/xxl-job-admin
admin/123456
至此,调度中心(xxl-job-admin)部署完成
2、配置执行器
执行器:xxl-job-executor-sample-springboot,可直接使用或者将此模块与业务代码整合;
作用:负责接收,调度中心,的调度并执行任务逻辑;
(1)使用intellij 在已有项目下新建微服务,job-executor,目录结构如下:
模仿官方的例子:xxl-job-executor-sample-springboot
job-executor
|___pom.xml
|___src
|___main
|___java
| |___com.unicom
| |___executor
| |__feign 服务间调用,写业务逻辑
| |__config
| | |__XxlJobConfig.java
| |__jobhandler
| | |__assets
| | |__AssetsTask.java
| | |__device
| | |__DeviceTask.java
| |__JobExecutorApplication.java
|___resources
|__application.properties
|__application-prod.properties
(2)引入 xxl-job-core 的maven依赖:
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.3.1</version>
</dependency>
(3)项目的配置文件application.properties中,加入关于xxl-job的配置信息:
### 官方样例文件的位置:/xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/resources/application.properties
### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://192.168.202.63:30080/xxl-job-admin
### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=default_token
### 执行器AppName
xxl.job.executor.appname=executor-assets
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
xxl.job.executor.ip=
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=8099
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=/data/applogs/xxl-job/jobhandler
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=8
(4) 创建启动类 JobExecutorApplication.java
// 官方样例文件的位置:xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/XxlJobExecutorApplication.java
package com.unicom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* @Author: sunkaiyuan
* @Date: 2023-02-09 11:02
* @Desperation: 创建启动类
*/
@SpringBootApplication
public class JobExecutorApplication {
public static void main(String[] args) {
SpringApplication.run(JobExecutorApplication.class, args);
}
}
(5)创建一个XxlJobConfig.java类,进行扫描JobHandler的位置:
// 官方样例文件的位置:xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/core/config/XxlJobConfig.java
package com.unicom.executor.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;
/**
* @Author: sunkaiyuan
* @Date: 2023-02-09 14:18
* @Desperation: 创建一个XxlJobConfig.java类,进行扫描JobHandler的位置
*/
@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;
}
}
(6)创建一个定时任务类JobHandler/AssetsTask.java
// 官方样例文件的位置:xxl-job/xxl-job-executor-samples/xxl-job-executor-sample-springboot/src/main/java/com/xxl/job/executor/service/jobhandler/SampleXxlJob.java
package com.unicom.executor.jobhandler.assets;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
* @Author: sunkaiyuan
* @Date: 2023-02-09 14:24
* @Desperation: TODO
*/
@Component
public class AssetsTask {
/**
* XxlJob开发示例(Bean模式)
*
* 开发步骤:
* 1、任务开发:在Spring Bean实例中,开发Job方法;
* 2、注解配置:为Job方法添加注解 "@XxlJob(value="自定义jobhandler名称", init = "JobHandler初始化方法", destroy = "JobHandler销毁方法")",注解value值对应的是调度中心新建任务的JobHandler属性的值。
* 3、执行日志:需要通过 "XxlJobHelper.log" 打印执行日志;
* 4、任务结果:默认任务结果为 "成功" 状态,不需要主动设置;如有诉求,比如设置任务结果为失败,可以通过 "XxlJobHelper.handleFail/handleSuccess" 自主设置任务结果;
*
* @author xuxueli 2019-12-11 21:52:51
*/
private static Logger logger = LoggerFactory.getLogger(AssetsTask.class);
/**
* 1、简单任务示例(Bean模式)
*/
@XxlJob("demoJobHandler")
public void demoJobHandler() throws Exception {
XxlJobHelper.log("XXL-JOB, Hello World.");
System.out.println("XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
System.out.println("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
// default success
}
}
(7)至此执行器所有的配置完成,下面去调度中心的web界面上新建执行器:
新建执行器路径:执行器管理 - 新增 - 新增执行器:
AppName: executor-assets (要和配置文件application.properties中appname保持一直)
名称: 资产执行器
注册方式: 手动录入
机器地址: http://192.168.5.18:8099/
新建任务:任务管理 - 新增 - 新增任务:
执行器: 资产执行器 (选择上一步新建的资产执行器)
任务描述: 随便写点啥
负责人: 随便写点啥
调度类型: 固定速率 (根据需求设定crontab)
固定速度: 30 (每30s执行一次)
运行模式: BEAN
JobHandler demoJobHandler (和定时任务类AssetsTask.java中的注解@XxlJob("demoJobHandler")保持一致)
路由策略: 第一个
调度过期策略: 立即执行一次
新建任务完成之后,立即执行一次,查看任务执行情况,查看返回结果,至此所有的配置结束;