一、简介
xxljob是一款开源的任务调度框架,它支持分布式、集群、高可用的任务调度服务,可以满足不同场景的任务调度需求。它提供了基于RESTful API的简单、易用的接口,可以方便地实现任务的创建、修改、删除、查询等操作。
官网地址:https://www.xuxueli.com/xxl-job
二、 安装和配置
1. 下载源码
github地址:http://github.com/xuxueli/xxl-job
gitee地址:https://gitee.com/xuxueli0323/xxl-job
源码结构:
xxl-job-admin:调度中心
xxl-job-core:公共依赖
xxl-job-executor-samples:执行器Sample示例(选择合适的版本执行器,可直接使用,也可以参考其并将现有项目改造成执行器)
:xxl-job-executor-sample-springboot:Springboot版本,通过Springboot管理执行器,推荐这种方式;
:xxl-job-executor-sample-frameless:无框架版本;
2. 初始化表结构
执行项目中doc/db目录下的tables_xxl_job.sql文件,初始化表结构:
3. 配置部署调度中心
调度中心配置文件地址:
/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
spring.mail.username=xxx@qq.com
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
4. 打包部署
## 打包项目
mvn clean compile package install
## 找到打包后的jar包目录下
java -jar xxl-job-admin-2.4.1-SNAPSHOT.jar
调度中心访问地址:
http://localhost:8080/xxl-job-admin
三、Springboot项目接入XXL-JOB
1. 引入依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>${project.parent.version}</version>
</dependency>
2. 执行器配置
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
3. 基于注解@XxlJob来定义定时任务的JobHandler
@Slf4j
@Component
public class MyJobHandler {
@Autowired
private ISchoolFileConfigService schoolFileConfigService;
@XxlJob("lessExpireSchoolFileJob")
public ReturnT<String> lessExpireSchoolFileJob(String param) {
String jobParam = XxlJobHelper.getJobParam();
return ReturnT.SUCCESS;
}
}
4. 封装调度中心的接口
到此,xxl-job已成功安装,并支持用户在界面配置定时任务。但是在项目开发中一般需要系统能够通过接口自动配置任务,因此本文给出了封装接口的示例:
4.1 通过登录接口获取cookie
通过抓包发现,xxl-job的所有接口都需要在Headers中添加cookie来保证安全性,该cookie可通过用户名和密码调用/login接口得到,因此我们可以先使用login接口获取cookie并保存下来,在之后的每次请求中都携带上,就能正常进行接口调用。
private final Map<String,String> loginCookie=new HashMap<>();
public void login() {
String url=adminAddresses+"/login";
HttpResponse response = HttpRequest.post(url)
.form("userName",username)
.form("password",password)
.execute();
List<HttpCookie> cookies = response.getCookies();
Optional<HttpCookie> cookieOpt = cookies.stream()
.filter(cookie -> cookie.getName().equals("XXL_JOB_LOGIN_IDENTITY")).findFirst();
if (!cookieOpt.isPresent())
throw new RuntimeException("get xxl-job cookie error!");
String value = cookieOpt.get().getValue();
loginCookie.put("XXL_JOB_LOGIN_IDENTITY",value);
}
4.2 接口示例
以查询任务列表接口为例:
public List<XxlJobInfo> getJobInfo(Integer jobGroupId,String executorHandler) {
String url=adminAddresses+"/jobinfo/pageList";
HttpResponse response = HttpRequest.post(url)
.form("jobGroup", jobGroupId)
.form("executorHandler", executorHandler)
.form("triggerStatus", -1)
.cookie(jobLoginService.getCookie())
.execute();
String body = response.body();
JSONArray array = JSONUtil.parse(body).getByPath("data", JSONArray.class);
List<XxlJobInfo> list = array.stream()
.map(o -> JSONUtil.toBean((JSONObject) o, XxlJobInfo.class))
.collect(Collectors.toList());
return list;
}