针对业务的不断发展,传统的调度任务管理,比如:Timer、Quartz将会出现一定的瓶颈,比如现在的工程,通过微服务来搭建,一个主服务管理调度任务,所有的服务在一台服务器里管理,执行任务通过不同微服务来调用,这样造成调度中心非常重,慢慢的服务管理及服务调用急需拆分出去。
问题一:调用API的的方式操作任务,不人性化;
问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;
问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。
目前部分服务列表,如下图:
服务已经比较多了,这样带来请求及服务资源压力。即使通过多服务集群来处理,也得约定好启动不同服务的配置,比较麻烦。
显然传统的定时任务已经不满足现在的分布式架构,所以需要一个分布式任务调度平台,目前根据比较,最终选择xxl-job。
xxl-job中心式的调度平台轻量级,开箱即用,操作简易,上手快,与SpringBoot有非常好的集成,而且监控界面就集成在调度中心,界面又简洁,对于企业维护起来成本不高,还有失败的邮件告警等等。所以,我们选择升级。
首先了解一下XXL-JOB架构图:
从架构图可以看出,分别有调度中心和执行器两大组成部分
其中调度中心,根据目前当前系统是微服务架构,需要把xxl-jbo前端代码改造成前后端分离项目集成进来。通过系统的权限管理,而不是xxl-job来管理,舍弃XXL-JOB用户管理和登录管理。
集成springcloud+nacos
增加拦截器:
package com.xxl.job.admin.config;
import com.tsingsoft.common.intercepter.PermissionInterceptor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.ArrayList;
import java.util.List;
/**
* 系统访问相关配置
*
* @author bask
*/
@Configuration
@Primary
@RefreshScope
public class WebConfiguration implements WebMvcConfigurer {
@Value("${my.swagger.show:true}")
private boolean swaggerShow;
/**
* 是否支持本地服务,即非微服务。
*/
@Value("${my.local.server:true}")
private boolean localServer;
@Override
public void addInterceptors(InterceptorRegistry registry) {
List patterns = filterPatterns();
// 通过拦截service请求下的链接进行token验证。
registry.addInterceptor(getPermissionInterceptor()).addPathPatterns("/**")
.excludePathPatterns(patterns);
}
/**
* 过滤掉不需要令牌验证的请求项
*
* @return 不需要令牌验证的请求项
*/
private List filterPatterns() {
List patterns = new ArrayList<>();
// 需要跳过的资源信息,并且必须在请求上增加@ResponseBody
patterns.add("/user/**");
// 需要跳过的资源信息,并且必须在请求上增加@ResponseBody
patterns.add("/sys/**");
patterns.add("/log/**");
patterns.add("/favicon.ico");
patterns.add("/example");
patterns.add("/error/**");
patterns.add("/assets/**");
patterns.add("/js/**");
patterns.add("/css/**");
// 如何任务调度中心不集成微服务,作为独立服务,则可以直接访问。
if(localServer){
// xxl-job 任务接口
// 过滤条件,根据实现情况补充
}
return patterns;
}
@Bean
PermissionInterceptor getPermissionInterceptor() {
return new PermissionInterceptor();
}
}
系统通过前端指定前缀,通过网关转发到xxl-job-admin服务(调度中心)进行服务数据响应。
因xxl-job默认采用netty来做服务间通信,这样通信在微服务中会造成端口浪费,因此,改成http形式请求,改造代码如下:
package com.xxl.job.core.controller;
import com.xxl.job.core.biz.impl.ExecutorBizImpl;
import com.xxl.job.core.biz.model.*;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
* 只提供/beat、/idelBeat、/run、/kill、/log 五个接口,所有请求的处理都会委托给executorBiz处理
* 的替换
* @author bask
*/
@RestController
public class XxlJobController {
@PostMapping("/beat")
public ReturnT beat() {
return new ExecutorBizImpl().beat();
}
@PostMapping("/idleBeat")
public ReturnT idleBeat(@RequestBody IdleBeatParam param) {
return new ExecutorBizImpl().idleBeat(param);
}
@PostMapping("/run")
public ReturnT run(@RequestBody TriggerParam param) {
return new ExecutorBizImpl().run(param);
}
@PostMapping("/kill")
public ReturnT kill(@RequestBody KillParam param) {
return new ExecutorBizImpl().kill(param);
}
@PostMapping("/log")
public ReturnT log(@RequestBody LogParam param) {
return new ExecutorBizImpl().log(param);
}
}
1、 调度中心先启动
2、执行器启动,并通过配置的调度中心address,自动(手动)注册到调度中心中。
3、在调度中心管理执行器。
4、在调度中心配置调度任务,指定运行某个执行器的具体业务任务,达到任务触发条件时,调度中心下发任务。
5、执行器的回调线程消费内存队列中的执行结果,主动上报给调度中心
5、当用户在调度中心查看任务日志,调度中心请求任务执行器,任务执行器读取任务日志文件并返回日志详情。
详细使用和操作文档,可参考官方文档,比较详细:https://www.xuxueli.com/xxl-job/
调度中心:
读取nacos中心配置
spring:
application:
name: ts-job
main:
allow-bean-definition-overriding: true
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: 192.168.0.53:8848
config:
server-addr: 192.168.0.53:8848
prefix: ts-job # nacos -> data-id = prefix+'-'+profile+file-extension,即:ts-auth-dev.yaml
group: DEFAULT_GROUP
file-extension: properties
refresh-enabled: true
mybatis:
configuration:
jdbc-type-for-null: 'null'
### xxl-job, access token
xxl.job.accessToken=123456
### xxl-job, i18n (default is zh_CN, and you can choose "zh_CN", "zh_TC" and "en")
xxl.job.i18n=zh_CN
## xxl-job, triggerpool max size
xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100
### xxl-job, log retention days
xxl.job.logretentiondays=30
### xml扫描,多个目录用逗号或者分号分隔(告诉 Mapper 所对应的 XML 文件位置)
mybatis-plus.mapper-locations=classpath:/mybatis-mapper/*Mapper.xml
my.local.server=false
留言与评论(共有 0 条评论) “” |