xxl-job架构原理讲解

2024-06-04 7226阅读

1、调度中心

调度中心是一个单独的Web服务,主要是用来触发定时任务的执行

它提供了一些页面操作,我们可以很方便地去管理这些定时任务的触发逻辑

调度中心依赖数据库,所以数据都是存在数据库中的

调度中心也支持集群模式,但是它们所依赖的数据库必须是同一个

所以同一个集群中的调度中心实例之间是没有任何通信的,数据都是通过数据库共享的

xxl-job架构原理讲解 第1张

2、执行器

执行器是用来执行具体的任务逻辑的

执行器你可以理解为就是平时开发的服务,一个服务实例对应一个执行器实例

每个执行器有自己的名字,为了方便,你可以将执行器的名字设置成服务名

3、任务

一个执行器中也是可以有多个任务的

总的来说,调用中心是用来控制定时任务的触发逻辑,而执行器是具体执行任务的,这是一种任务和触发逻辑分离的设计思想,这种方式的好处就是使任务更加灵活,可以随时被调用,还可以被不同的调度规则触发。

xxl-job架构原理讲解 第2张

来个Demo

1、搭建调度中心

调度中心搭建很简单,先下载源码

github.com/xuxueli/xxl…

然后改一下数据库连接信息,执行一下在项目源码中的/doc/db下的sql文件

xxl-job架构原理讲解 第3张

启动可以打成一个jar包,或者本地启动就是可以的

启动完成之后,访问下面这个地址就可以访问到控制台页面了

http://localhost:8080/xxl-job-admin/toLogin

用户名密码默认是 admin/123456

2、执行器和任务添加

添加一个名为sanyou-xxljob-demo执行器

xxl-job架构原理讲解 第4张

任务添加

xxl-job架构原理讲解 第5张

执行器选择我们刚刚添加的,指定任务名称为TestJob,corn表达式的意思是每秒执行一次

创建完之后需要启动一下任务,默认是关闭状态,也就不会执行

xxl-job架构原理讲解 第6张

创建执行器和任务其实就是CRUD,并没有复杂的业务逻辑

按照如上配置的整个Demo的意思就是

每隔1s,执行一次sanyou-xxljob-demo这个执行器中的TestJob任务

3、创建执行器和任务

引入依赖

    
        org.springframework.boot
        spring-boot-starter-web
        2.2.5.RELEASE
    
    
        com.xuxueli
        xxl-job-core
        2.4.0
    

配置XxlJobSpringExecutor这个Bean

@Configuration
public class XxlJobConfiguration {
    @Bean
    public XxlJobSpringExecutor xxlJobExecutor() {
        XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
        //设置调用中心的连接地址
        xxlJobSpringExecutor.setAdminAddresses("http://localhost:8080/xxl-job-admin");
        //设置执行器的名称
        xxlJobSpringExecutor.setAppname("sanyou-xxljob-demo");
        //设置一个端口,后面会讲作用
        xxlJobSpringExecutor.setPort(9999);
        //这个token是保证访问安全的,默认是这个,当然可以自定义,
        // 但需要保证调度中心配置的xxl.job.accessToken属性跟这个token是一样的
        xxlJobSpringExecutor.setAccessToken("default_token");
        //任务执行日志存放的目录
        xxlJobSpringExecutor.setLogPath("./");
        return xxlJobSpringExecutor;
    }
}

XxlJobSpringExecutor这个类的作用,后面会着重讲

通过@XxlJob指定一个名为TestJob的任务,这个任务名需要跟前面页面配置的对应上

@Component
public class TestJob {
    private static final Logger logger = LoggerFactory.getLogger(TestJob.class);
    @XxlJob("TestJob")
    public void testJob() {
        logger.info("TestJob任务执行了。。。");
    }
}

所以如果顺利的话,每隔1s钟就会打印一句TestJob任务执行了。。。

启动项目,注意修改一下端口,因为调用中心默认也是8080,本地起会端口冲突

最终执行结果如下,符合预期

xxl-job架构原理讲解 第7张

讲完概念和使用部分,接下来就来好好讲一讲Xxl-Job核心的实现原理

从执行器启动说起

前面Demo中使用到了一个很重要的一个类

XxlJobSpringExecutor

这个类就是整个执行器启动的入口xxl-job架构原理讲解 第8张

这个类实现了SmartInitializingSingleton接口

所以经过Bean的生命周期,一定会调用afterSingletonsInstantiated这个方法的实现

这个方法干了很多初始化的事,这里我挑三个重要的讲,其余的等到具体的功能的时候再提

1、初始化JobHandler

JobHandler是个什么?

所谓的JobHandler其实就是一个定时任务的封装

xxl-job架构原理讲解 第9张

一个定时任务会对应一个JobHandler对象

当执行器执行任务的时候,就会调用JobHandler的execute方法

JobHandler有三种实现:

  • MethodJobHandler
  • GlueJobHandler
  • ScriptJobHandler

    MethodJobHandler是通过反射来调用方法执行任务

    xxl-job架构原理讲解 第10张

    所以MethodJobHandler的任务的实现就是一个方法,刚好我们demo中的例子任务其实就是一个方法

    所以Demo中的任务最终被封装成一个MethodJobHandler

    GlueJobHandler比较有意思,它支持动态修改任务执行的代码

    当你在创建任务的时候,需要指定运行模式为GLUE(Java)

    xxl-job架构原理讲解 第11张

    之后需要在操作按钮点击GLUE IDE编写Java代码

    xxl-job架构原理讲解 第12张

    代码必须得实现IJobHandler接口,之后任务执行的时候就会执行execute方法的实现

    如果你需要修改任务的逻辑,只需要重新编辑即可,不需要重启服务

    ScriptJobHandler,通过名字也可以看出,是专门处理一些脚本的

    运行模式除了BEAN和GLUE(Java)之外,其余都是脚本模式

    而本节的主旨,所谓的初始化JobHandler就是指,执行器启动的时候会去Spring容器中找到加了@XxlJob注解的Bean

    解析注解,然后封装成一个MethodJobHandler对象,最终存到XxlJobSpringExecutor成员变量的一个本地的Map缓存中

    xxl-job架构原理讲解 第13张

    缓存key就是任务的名字

    xxl-job架构原理讲解 第14张

    至于GlueJobHandler和ScriptJobHandler都是任务触发时才会创建

    除了上面这几种,你也自己实现JobHandler,手动注册到JobHandler的缓存中,也是可以通过调度中心触发的

    2、创建一个Http服务器

    除了初始化JobHandler之外,执行器还会创建一个Http服务器

    这个服务器端口号就是通过XxlJobSpringExecutor配置的端口,demo中就是设置的是9999,底层是基于Netty实现的

    xxl-job架构原理讲解 第15张

    这个Http服务端会接收来自调度中心的请求

    当执行器接收到调度中心的请求时,会把请求交给ExecutorBizImpl来处理

    xxl-job架构原理讲解 第16张

    这个类非常重要,所有调度中心的请求都是这里处理的

    ExecutorBizImpl实现了ExecutorBiz接口

    当你翻源码的时候会发现,ExecutorBiz还有一个ExecutorBizClient实现

    xxl-job架构原理讲解 第17张

    ExecutorBizClient的实现就是发送http请求,所以这个实现类是在调度中心使用的,用来访问执行器提供的http接口

    xxl-job架构原理讲解 第18张

    3、注册到调度中心

    当执行器启动的时候,会启动一个注册线程,这个线程会往调度中心注册当前执行器的信息,包括两部分数据

    • 执行器的名字,也就是设置的appname
    • 执行器所在机器的ip和端口,这样调度中心就可以访问到这个执行器提供的Http接口

      前面提到每个服务实例都会对应一个执行器实例,所以调用中心会保存每个执行器实例的地址

      xxl-job架构原理讲解 第19张

      这里你可以把调度中心的功能类比成注册中心

      任务触发原理

      弄明白执行器启动时干了哪些事,接下来讲一讲Xxl-Job最最核心的功能,那就是任务触发的原理

      任务触发原理我会分下面5个小点来讲解

      • 任务如何触发?
      • 快慢线程池的异步触发任务优化
      • 如何选择执行器实例?
      • 执行器如何去执行任务?
      • 任务执行结果的回调
        1、任务如何触发?

        调度中心在启动的时候,会开启一个线程,这个线程的作用就是来计算任务触发时机,这里我把这个线程称为调度线程

        这个调度线程会去查询xxl_job_info这张表

        这张表存了任务的一些基本信息和任务下一次执行的时间

        调度线程会去查询下一次执行的时间


    免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

    目录[+]