微服务调度中心升级xxl-job及xxl-job改造

针对业务的不断发展,传统的调度任务管理,比如:Timer、Quartz将会出现一定的瓶颈,比如现在的工程,通过微服务来搭建,一个主服务管理调度任务,所有的服务在一台服务器里管理,执行任务通过不同微服务来调用,这样造成调度中心非常重,慢慢的服务管理及服务调用急需拆分出去。

Quartz的不足

问题一:调用API的的方式操作任务,不人性化;
问题二:需要持久化业务QuartzJobBean到底层数据表中,系统侵入性相当严重。
问题三:调度逻辑和QuartzJobBean耦合在同一个项目中,这将导致一个问题,在调度任务数量逐渐增多,同时调度任务逻辑逐渐加重的情况加,此时调度系统的性能将大大受限于业务;
问题四:quartz底层以“抢占式”获取DB锁并由抢占成功节点负责运行任务,会导致节点负载悬殊非常大;而XXL-JOB通过执行器实现“协同分配式”运行任务,充分发挥集群优势,负载各节点均衡。

目前部分服务列表,如下图:


微服务调度中心升级xxl-job及xxl-job改造

服务已经比较多了,这样带来请求及服务资源压力。即使通过多服务集群来处理,也得约定好启动不同服务的配置,比较麻烦。

显然传统的定时任务已经不满足现在的分布式架构,所以需要一个分布式任务调度平台,目前根据比较,最终选择xxl-job。

xxl-job中心式的调度平台轻量级,开箱即用,操作简易,上手快,与SpringBoot有非常好的集成,而且监控界面就集成在调度中心,界面又简洁,对于企业维护起来成本不高,还有失败的邮件告警等等。所以,我们选择升级。

首先了解一下XXL-JOB架构图:


微服务调度中心升级xxl-job及xxl-job改造

从架构图可以看出,分别有调度中心和执行器两大组成部分

调度中心。负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。支持可视化界面,可以在调度中心对任务进行新增,更新,删除,会实时生效。支持监控调度结果,查看执行日志,查看调度任务统计报表,任务失败告警等等。

执行器。负责接收调度请求,执行调度任务的业务逻辑。执行器启动后需要注册到调度中心。接收调度中心的发出的执行请求,终止请求,日志请求等等。

其中调度中心,根据目前当前系统是微服务架构,需要把xxl-jbo前端代码改造成前后端分离项目集成进来。通过系统的权限管理,而不是xxl-job来管理,舍弃XXL-JOB用户管理和登录管理。

XXL-JOB-ADMIN 微服务集成

集成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


执行器配置


微服务调度中心升级xxl-job及xxl-job改造

中心   xxl
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章