分布式任务调度平台XXL-JOB官方架构设计图-集成
定时任务几乎是每位业务系统必不可少的功能,估算到期时间、过期时间等,定时触发某项任务操作。在使用单体应用时,基本使用提供的注解即可实现定时任务,而在使用微服务集群时,这些方法就该考虑添加分布式锁来避免多个微服务同时运行定时任务而造成同一个任务重复执行。
不仅使用注解,目前也有一种方法,就是搭建分布式任务平台,所有的微服务注册到分布式任务平台,由分布式任务平台统一调度,那样避开了同一任务被重复执行。这儿我们选择使用XXL-JOB作为分布式任务调度平台,XXL-JOB核心设计目标是开发快速、学习简略、轻量级、易扩充。
使用分布式任务调度平台的特点不仅防止同一任务重复执行外,也有使用简略,可以自动执行、有详尽的调度日志查看任务详细执行状况等特点。
XXL-JOB官方构架设计图:
下边我们根据方法来介绍,怎么结合我们的微服务平台将分布式任务调度平台XXL-JOB集成过来,实现我们还要的定时任务功能。
一、微服务框架整合xxl-job-、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:无框架版本;
下载出来的开源包有三个目录:xxl-job-admin、xxl-job-core和xxl-job--,顾名思义,xxl-job-admin是分布式任务平台的服务端参予理台,我们还要布署的只是这个安装工程任务平台,我们可以把整个安装工程集成到我们的微服务中,统一打包布署;xxl-job-core是公共依赖包,我们其他还要实现定时任务的微服务须要引进这个包来实现定时任务执行器。xxl-job--为定时任务执行器的例子代码。
2、在基础平台-安装工程--bom中引进xxl-job-core核心包,统一版本管理。
......
2.3.1
......
com.xuxueli
xxl-job-core
${xxl-job.version}
3、将xxl-job-admin集成到微服务安装工程中,便于统一打包布署
按照我们的微服务构架设计,-作为我们系统的插件安装工程,上面放置我们还要的插件服务。有些插件是应当的,而有些插件或许会用不到,此刻我们就可以按照自己的业务需求去选择布署业务插件。
为和我们的微服务深度集成就不是时延的特点,我们还要对xxl-job-admin的配置文件进行适当的更改:
gitegg-plugin
com.gitegg.cloud
1.0.1.RELEASE
4.0.0
gitegg-job
${project.artifactId}
jar
UTF-8
UTF-8
UTF-8
1.8
1.8
true
4.1.63.Final
2.9.0
5.3.20
2.6.7
2.2.2
8.0.29
1.7.36
5.8.2
1.3.2
3.0.10
3.2.1
3.4.0
3.0.1
com.gitegg.platform
gitegg-platform-boot
com.gitegg.platform
gitegg-platform-cloud
org.mybatis.spring.boot
mybatis-spring-boot-starter
${mybatis-spring-boot-starter.version}
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-freemarker
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-mail
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter
mysql
mysql-connector-java
${mysql-connector-java.version}
com.xuxueli
xxl-job-core
org.slf4j
slf4j-api
com.google.cloud.tools
jib-maven-plugin
.yml配置:
server:
port: 8007
spring:
profiles:
active: '@spring.profiles.active@'
application:
name: '@artifactId@'
cloud:
inetutils:
ignored-interfaces: docker0
nacos:
discovery:
server-addr: ${spring.nacos.addr}
config:
server-addr: ${spring.nacos.addr}
file-extension: yaml
extension-configs:
# 必须带文件扩展名,此时 file-extension 的配置对自定义扩展配置的 Data Id 文件扩展名没有影响
- data-id: ${spring.nacos.config.prefix}.yaml
group: ${spring.nacos.config.group}
refresh: true
- data-id: ${spring.nacos.config.prefix}-xxl-job.yaml
group: ${spring.nacos.config.group}
refresh: true
### xxl-job-admin config
mvc:
servlet:
load-on-startup: 0
static-path-pattern: /static/**
resources:
static-locations: classpath:/static/
### freemarker
freemarker:
templateLoaderPath: classpath:/templates/
suffix: .ftl
charset: UTF-8
request-context-attribute: request
settings.number_format: 0.##########
### actuator
management:
server:
servlet:
context-path: /actuator
health:
mail:
enabled: false
### mybatis
mybatis:
mapper-locations: classpath:/mybatis-mapper/*Mapper.xml
Nacos上-cloud--xxl-job.yaml配置:
server:
servlet:
context-path: /xxl-job-admin
spring:
datasource:
url: jdbc:mysql://127.0.0.1/xxl_job?useSSL=false&zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
### datasource-pool
type: com.zaxxer.hikari.HikariDataSource
hikari:
minimum-idle: 10
maximum-pool-size: 30
auto-commit: true
idle-timeout: 30000
pool-name: HikariCP
max-lifetime: 900000
connection-timeout: 10000
connection-test-query: SELECT 1
validation-timeout: 1000
### email
mail:
host: smtp.qq.com
port: 25
username: xxx@qq.com
from: xxx@qq.com
password: xxx
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
socketFactory:
class: javax.net.ssl.SSLSocketFactory
### xxl-job, access token
xxl:
job:
accessToken: default_token
### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")
i18n: zh_CN
## xxl-job, triggerpool max size
triggerpool:
fast:
max: 200
slow:
max: 100
### xxl-job, log retention days
logretentiondays: 30
4、初始化xxl-job-admin还要的数据库脚本
初始化脚本储存在下载的包目录的\xxl-job-2.3.1\doc\db\.sql中,一共还要8张表。我们将xxl-job-admin的数据库和业务数据库分开,配置不同的数据源任务平台,在Nacos配置单独的xxl-job-admin配置文件。
5、在安装工程的父级pom.xml下添加静态文件过滤
xxl-job-admin是项目,其后端页面由ftl文件和静态文件组成,默认状况下maven启用分环境调用配置时,会对目录下的@进行替换,致使静态文件下的图标文件不能用,因此,这儿还要进行和jks文件一样的过滤配置:
src/main/resources
true
**/*.jks
static/**
src/main/resources
false
**/*.jks
static/**
src/main/java
**/*.xml
6、在添加xxl-job-admin路由转发
xxl-job-admin路由转发还要添加两方面内容,一个是xxl-job-admin注册到Nacos注册中心上的-job服务,一个是xxl-job-admin后端页面恳求的静态文件转发。第一个是为了和我们整体微服务保持一致,第二个是为了解决xxl-job-admin后端ftl页面在恳求静态文件时,恳求的是/xxl-job-admin根路径。新增路由转发配置如下:
- id: gitegg-job
uri: lb://gitegg-job
predicates:
- Path=/gitegg-job/**
filters:
- StripPrefix=1
- id: xxl-job-admin
uri: lb://gitegg-job
predicates:
- Path=/xxl-job-admin/**
filters:
- StripPrefix=0
7、增加xxl-job-admin访问白名单
xxl-job-admin有自己的权限访问控制,我们不在网段对其进行信令,因此在Nacos配置中,提高白名单配置:
# 网关放行设置 1、whiteUrls不需要鉴权的公共url,白名单,配置白名单路径 2、authUrls需要鉴权的公共url
oauth-list:
......
whiteUrls:
......
- "/gitegg-job/**"
- "/xxl-job-admin/**"
......
8、启动xxl-job-admin微服务,查看是否启动成功,默认用户名密码:admin/
二、测试XXL-JOB定时任务功能
我们在后面的第一步中,完成了xxl-job-admin的整合和启动,xxl-job-admin可以看做是分布式任务的服务注册中心和管理台,假如我们还要实现定时任务,还须要详细实现执行器让xxl-job-admin读取执行。
XXL-JOB支持多种形式的定时任务读取,可以将定时任务执行器写在业务代码中,也可以写在xxl-job-admin服务端:
1、增加xxl-job通用配置
新增--xxl-job安装工程,提高通用配置.java通用配置,那样在须要使用定时任务的微服务中,只须要引进一次即可,不须要重复配置。
.java:
package com.gitegg.platform.xxl.job.config;
import com.xxl.job.core.executor.impl.XxlJobSpringExecutor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* xxl-job config
*
* @author xuxueli 2017-04-28
*/
@Slf4j
@Configuration
public class XxlJobConfig {
@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() {
log.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;
}
/**
* 针对多网卡、容器内部署等情况,可借助 "spring-cloud-commons" 提供的 "InetUtils" 组件灵活定制注册IP;
*
* 1、引入依赖:
*
* org.springframework.cloud
* spring-cloud-commons
* ${version}
*
*
* 2、配置文件,或者容器启动变量
* spring.cloud.inetutils.preferred-networks: 'xxx.xxx.xxx.'
*
* 3、获取IP
* String ip_ = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
*/
}
Nacos配置中心:
xxl:
job:
admin:
addresses: http://127.0.0.1/xxl-job-admin
accessToken: 'default_token'
executor:
appname: ${spring.application.name}
address:
ip:
port: 9999
logpath: D:\\log4j2_nacos\\xxl-job\\jobhandler
logretentiondays: 30
2、实现定时任务检测代码
我们在--中检测定时任务执行器,先在pom.xml中添加--xxl-job依赖,之后新增.java检测类
.java:
package com.gitegg.service.system.jobhandler;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.util.concurrent.TimeUnit;
/**
* 定时任务示例代码,其他更多示例请查看
* https://www.xuxueli.com/xxl-job
* @author GitEgg
*/
@Slf4j
@Component
public class SystemJobHandler {
/**
* 1、简单任务示例(Bean模式)不带返回值
*/
@XxlJob("systemJobHandler")
public void systemJobHandler() throws Exception {
XxlJobHelper.log("不带返回值:XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
}
/**
* 2、简单任务示例(Bean模式)带成功或失败返回值
*/
@XxlJob("userJobHandler")
public ReturnT userJobHandler() throws Exception {
XxlJobHelper.log("带返回值:XXL-JOB, Hello World.");
for (int i = 0; i < 5; i++) {
XxlJobHelper.log("beat at:" + i);
TimeUnit.SECONDS.sleep(2);
}
return ReturnT.SUCCESS;
}
}
3、配置xxl-job-admin新增执行器4、新增xxl-job-admin任务
执行器可以看做是一组微服务,而任务是微服务详细执行的步骤。任务新增后,默认是STOP状态,还要自动启动,当列表显示时,表示该任务是运行状态,会依照配置的时间执行。
5、查看执行器是否执行
在本地开发环境查看任务执行的方法有多种,直接Debug也可以,生产环境我们可以查看xxl-job日志,在检测代码中记录的log,在xxl-job-admin管理台都可以具体查看。
通过以上操作方法,我们将xxl-job和xxl-job-admin整合到了我们的微服务构架中,只须要在有任务调度需求的微服务中实现执行器就可以满足我们的需求了。
源码地址:
:是一款开源免费的企业级微服务应用开发框架,借以整合现今主流稳定的开源技术框架,集成常用的最佳项目解决方案,实现可直接使用的微服务迅速开发框架。
-/:是一款开源免费的企业级微服务应用开发框架,进而整合现今主流稳定的开源技术框架,集成常用的最佳项目解决方案,实现可直接使用的微服务迅速开发框架。