定时工作简直是每个业务零碎必不可少的性能,计算到期工夫、过期工夫等,定时触发某项工作操作。在应用单体利用时,根本应用Spring提供的注解即可实现定时工作,而在应用微服务集群时,这种形式就要思考增加分布式锁来避免多个微服务同时运行定时工作而导致同一个工作反复执行。 除了应用注解,当初还有一种形式,就是搭建分布式工作平台,所有的微服务注册到分布式工作平台,由分布式工作平台对立调度,这样防止了同一工作被反复执行。这里咱们抉择应用XXL-JOB作为分布式任务调度平台,XXL-JOB外围设计指标是开发迅速、学习简略、轻量级、易扩大。 应用分布式任务调度平台的长处除了防止同一工作反复执行外,还有应用简略,能够手动执行、有具体的调度日志查看工作具体执行状况等长处。 XXL-JOB官网架构设计图: 上面咱们依照步骤来介绍,如何联合咱们的微服务平台将分布式任务调度平台XXL-JOB集成进来,实现咱们须要的定时工作性能。 一、微服务框架整合xxl-job-admin1、XXL-JOB开源网站下载源码,下载地址 https://github.com/xuxueli/xxl-job/releases ,下载下来的源码如下: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-executor-samples,顾名思义,xxl-job-admin是分布式工作平台的服务端兼治理台,咱们须要部署的也是这个工程,咱们能够把整个工程集成到咱们的微服务中,对立打包部署;xxl-job-core是公共依赖包,咱们其余须要实现定时工作的微服务须要引入这个包来实现定时工作执行器。xxl-job-executor-samples为定时工作执行器的实例代码。 2、在根底平台gitegg-platform工程gitegg-platform-bom中引入xxl-job-core外围包,对立版本治理。...... 2.3.1...... com.xuxueli xxl-job-core ${xxl-job.version} 3、将xxl-job-admin集成到微服务工程中,不便对立打包部署 依据咱们的微服务架构设计,gitegg-plugin作为咱们零碎的插件工程,外面搁置咱们须要的插件服务。有些插件是必须的,而有些插件可能会用不到,此时咱们就能够依据本人的业务需要去抉择部署业务插件。 为和咱们的微服务深度集成就不是解耦的个性,咱们须要对xxl-job-admin的配置文件进行适当的批改: 首先批改pom.xml,放弃各依赖库版本统一,批改parent标签,使其援用GitEgg工程的根底jar包和微服务配置注册性能,同时排除logback,应用log4j2记录日志 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 批改application.properties ,依据咱们零碎的标准,新增bootstrap.yml、bootstrap-dev.yml、bootstrap-prod.yml、bootstrap-test.yml文件。将application.properties局部配置,移到bootstrap.yml配置中。因xxl-job-admin独自数据库,且其默认应用的是Hikari数据库连接池,这里咱们不打算改变,依然使其放弃原有的数据库配置,咱们将可配置的内容搁置在Nacos微服务配置核心上,同时在bootstrap.yml中增加多yaml文件配置(请留神,在咱们本地应用的是yml结尾的文件,Nacos服务注册核心上应用的是yaml结尾的文件,两者是一样的,只是扩展名的不同)。bootstrap.yml配置: server: port: 8007spring: 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.############# actuatormanagement: server: servlet: context-path: /actuator health: mail: enabled: false### mybatismybatis: mapper-locations: classpath:/mybatis-mapper/*Mapper.xmlNacos上gitegg-cloud-config-xxl-job.yaml配置: server: servlet: context-path: /xxl-job-adminspring: 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 tokenxxl: 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: 304、初始化xxl-job-admin须要的数据库脚本 初始化脚本寄存在下载的包目录的\xxl-job-2.3.1\doc\db\tables_xxl_job.sql中,一共须要8张表。咱们将xxl-job-admin的数据库和业务数据库离开,配置不同的数据源,在Nacos配置独自的xxl-job-admin配置文件。 新建xxl_job数据库 关上数据库执行建表语句 5、在GitEgg工程的父级pom.xml下增加动态文件过滤 xxl-job-admin是SpringMVC我的项目,其前端页面由ftl文件和动态文件组成,默认状况下maven启用分环境读取配置时,会对resource目录下的@进行替换,导致动态文件下的字体文件不能用,所以,这里须要进行和jks文件一样的过滤配置: src/main/resources true **/*.jks static/** src/main/resources false **/*.jks static/** src/main/java **/*.xml 6、在Gateway增加xxl-job-admin路由转发 xxl-job-admin路由转发须要增加两方面内容,一个是xxl-job-admin注册到Nacos注册核心上的gitegg-job服务,一个是xxl-job-admin前端页面申请的动态文件转发。第一个是为了和咱们整体微服务保持一致,第二个是为了解决xxl-job-admin前端ftl页面在申请动态文件时,申请的是/xxl-job-admin根门路。新增Gateway路由转发配置如下: - 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=07、减少xxl-job-admin拜访白名单 xxl-job-admin有本人的权限访问控制,咱们不在网关对其进行鉴权,所以在Nacos配置中,减少白名单配置: # 网关放行设置 1、whiteUrls不须要鉴权的公共url,白名单,配置白名单门路 2、authUrls须要鉴权的公共urloauth-list:...... whiteUrls:...... - "/gitegg-job/**" - "/xxl-job-admin/**"......8、启动xxl-job-admin微服务,查看是否启动胜利,默认用户名明码: admin/123456 二、测试XXL-JOB定时工作性能 咱们在下面的第一步中,实现了xxl-job-admin的整合和启动,xxl-job-admin能够看做是分布式工作的服务注册核心和治理台,如果咱们须要实现定时工作,还须要具体实现执行器让xxl-job-admin调用执行。 XXL-JOB反对多种形式的定时工作调用,能够将定时工作执行器写在业务代码中,也能够写在xxl-job-admin服务端: BEAN模式(类模式): Bean模式工作,反对基于类的开发方式,每个工作对应一个Java类。BEAN模式(办法模式): Bean模式工作,反对基于办法的开发方式,每个工作对应一个办法。GLUE模式(Java/Shell/Python/NodeJS/PHP/PowerShell) :工作以源码形式保护在调度核心,反对通过Web IDE在线更新,实时编译和失效,因而不须要指定JobHandler。 1、减少xxl-job通用配置 新增gitegg-platform-xxl-job工程,减少通用配置XxlJobConfig.java通用配置,这样在须要应用定时工作的微服务中,只须要引入一次即可,不须要反复配置。 XxlJobConfig.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@Configurationpublic 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: 302、实现定时工作测试代码 咱们在gitegg-service-system中测试定时工作执行器,先在pom.xml中增加gitegg-platform-xxl-job依赖,而后新增SystemJobHandler.java测试类 SystemJobHandler.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@Componentpublic 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新增执行器新增时:gitegg-service-system服务启动后,主动注册: 4、新增xxl-job-admin工作 执行器能够看做是一组微服务,而工作是微服务具体执行的办法。工作新增后,默认是STOP状态,须要手动启动,当列表显示RUNNING时,示意该工作是运行状态,会依据配置的工夫执行。 5、查看执行器是否执行 在本地开发环境查看工作执行的形式有多种,间接Debug也能够,生产环境咱们能够查看xxl-job日志,在测试代码中记录的log,在xxl-job-admin治理台都能够具体查看。 通过以上操作步骤,咱们将xxl-job和xxl-job-admin整合到了咱们的微服务架构中,只须要在有任务调度需要的微服务中实现执行器就能够满足咱们的需要了。 GitEgg-Cloud是一款基于SpringCloud整合搭建的企业级微服务利用开发框架,开源我的项目地址:Gitee: https://gitee.com/wmz1930/GitEgg GitHub: https://github.com/wmz1930/GitEgg