xxl-job执行器启动及注册流程

1,467 阅读3分钟

一 springboot应用集成xxl-job

在使用springboot开发的应用中,引入xxl-job-core模块,就使项目具备了执行器的功能。

<dependency>
    <groupId>com.xuxueli</groupId>
    <artifactId>xxl-job-core</artifactId>
    <version>2.4.0</version>
</dependency>

添加配置,需提供以下信息。 image.png 创建XxlJobSpringExecutor的bean对象,并交由spring管理。 image.png 基于方法编写任务体,使用@XxlJob标注,指定任务名。 image.png 启动调度平台,进行任务配置。BEAN名称即@XxlJob的value值。 image.png

二 执行器的启动

XxlJobSpringExecutorXxlJobExecutor的子类,实现了SmartInitializingSingleton接口。当所有单例bean初始化完成后,spring会调用实现了该接口的bean的afterSingletonsInstantiated()方法。 来看该方法:

  • 先调用initJobHandlerMethodRepository(applicationContext),扫描@XxlJob标注的方法,包装成MethodJobHandler对象,添加到jobHandlerRepository的Map中。
// key即任务名
private static ConcurrentMap<String, IJobHandler> jobHandlerRepository = new ConcurrentHashMap<String, IJobHandler>();

MethodJobHandler是IJobHandler接口的一个实现,将通过反射执行任务体。 image.png image.png

  • 最后调用super.start(),完成上下文初始化。

2.1 XxlJobExecutor类

XxlJobExecutor是个核心类,持有所有配置,定义所有http请求的处理方式。

XxlJobExecutor.start()中完成以下工作,执行器将启动成功。 image.png 从中可知:

  1. 日志文件保存在执行器机器上,过期删除通过异步线程实现;
  2. 执行器与每个调度平台(集群部署),都有一个通信组件AdminBizImpl
  3. 执行器执行完任务,向调度平台异步汇报结果;
  4. 创建netty客户端,用于向调度平台发起注册、处理调度平台的指令。

三 执行器与调度平台的双向通信

com.xxl.job.core.biz.ExecutorBiz接口,定义了执行器面向调度平台的业务功能:响应心跳、响应空闲心跳、终止执行、读取执行日志、执行任务 image.png com.xxl.job.core.biz.AdminBiz接口,定义了调度平台面向执行器的业务功能:响应执行回调、注册、取消注册请求 image.png 可见,执行器和调度平台,是双向交互的。 image.png

四 执行器注册流程

XxlJobExecutor.start()中调用了initEmbedServer,创建EmbedServer实例。EmbedServer在异步线程中,创建netty客户端,来处理调度平台的请求,同时发起注册。 image.png 注册和取消注册,都在registryThread中完成。 image.png

4.1 续期

注册是周期性动作,每30秒发起一次。当执行器连续3次注册失败时,将被调度平台从执行器列表中移除。

这一点与eureka客户端的注册续期相似。

如果由调度平台主动向每个执行器发送心跳探测,来实现续期。那么,调度平台在性能、网络IO上将承受很大压力。

4.2 为什么向任意调度平台注册成功即可?

因为调度平台维护的执行器实例列表,在数据库表中保存,而不是进程内存。当调度平台采用集群部署时,并不需要在多个节点间做任何数据同步,只要有一个节点成功处理了注册请求即可。

所有节点都从数据库表读取同一份注册表记录。

4.3 beat接口不是心跳探测吗?

ExecutorBizImpl中有心跳实现。难道调度平台周期性向执行器发送心跳,来探测它是否在线,从而决定是否将它从注册表中移除? image.png 其实,beat接口用于故障转移路由策略(在xxl-job-admin模块的ExecutorRouteFailover类)。调度平台会依次向执行器发送beat请求,将第一个在线的执行器作为调度目标。 image.png

4.4 执行器处理请求

image.png 使用Netty接收来自调度平台的请求,并创建了maximumPoolSize = 200、队列长度=2000的线程池。 image.pngEmbedHttpServerHandler类,向线程池提交任务,来异步处理每个请求。 image.png image.png 根据请求url识别指令,指令的具体实现都在ExecutorBizImpl类。如处理kill请求: image.png