xxljob 客户端任务注册流程-springboot(1)
xxjob 版本-2.3.1
(1)XxlJobSpringExecutor 执行器类
这个类是xxlJob clent 端启动类,该执行器 继承了 XxlJobExecutor 接口,实现了ApplicationContextAware SmartInitializingSingleton, DisposableBean 接口
public class XxlJobSpringExecutor extends XxlJobExecutor implements ApplicationContextAware, SmartInitializingSingleton, DisposableBean
- ApplicationContextAware 作用是 当ioc容器初始化后,会调用setApplicationContext 方法,能从其中获取到ApplicationContext对象,ApplicationContext 对象包含了对ioc容器bean的操作。
- SmartInitializingSingleton 接口 作用是 当ioc容器基本实例化后,会调用afterSingletonsInstantiated 方法,该接口多用于对spring的扩展(自定义框架)
- DisposableBean 接口作用是 当spring销毁实现该接口的bean对象前,都会调用destroy 方法
(2)Spring 会通过回调 SmartInitializingSingleton#afterSingletonsInstantiated()方法,启动xxjob的客户端。
(1)初始化jobHandlerMethod 到本地注册表
从ioc中获取所有 @xxjob 注解类的实例bean(业务的job类)。
applicationContext.getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit)
- includeNonSingletons : 非单例
- allowEagerInit:是否允许对”懒加载"的Bean进行实例化
String[] beanDefinitionNames = applicationContext.getBeanNamesForType(Object.class, false, true); for (String beanDefinitionName : beanDefinitionNames) { Object bean = applicationContext.getBean(beanDefinitionName); Map<Method, XxlJob> annotatedMethods = null; // referred to :org.springframework.context.event.EventListenerMethodProcessor.processBean try { // 获取使用XxlJob 注解的方法 annotatedMethods = MethodIntrospector.selectMethods(bean.getClass(), new MethodIntrospector.MetadataLookup<XxlJob>() { @Override public XxlJob inspect(Method method) { // 获取有XxlJob 注解的方法实例(包括父层级) return AnnotatedElementUtils.findMergedAnnotation(method, XxlJob.class); } }); } catch (Throwable ex) { logger.error("xxl-job method-jobhandler resolve error for bean[" + beanDefinitionName + "].", ex); }
并将该Bean的实例,执行方法,初始化方法,销毁方法 包装成 MethodJobHandler 对象。并将该对象放入到jobHandlerRepository中
ConcurrentMap<String/*jobHandler名称*/, IJobHandler/*任务处理类*/> jobHandlerRepository // 客户端本地任务处理表
(2)刷新 GlueFactory
(3)调用父类执行器XxlJobExecutor#start()
(1)初始化客户端xxjob 客户端 的日志路径
(2)初始化 AdminBizClient
从配置文件中的 adminAddress 中获取到admin server的地址,配置多个地址就会创建 多个 AdminBizClient,并放入到 adminBizList集合中
AdminBizClient 是客户端对 admin server 的rpc 调用,包含了(任务注册,任务回调,任务移除)
(3)初始化客户端清除日志线程
(4)初始化触发器的回调线程
(5)初始化执行器注册服务
创建 EmbedServer 对象,并调用其start(address, port, appname, accessToken)方法 。EmbedServer 包含了客户端与服务端的很多交互,是客户端与服务的入口
// 调用 ExecutorRegistryThread 线程,向admin server 注册任务组 public void startRegistry(final String appname, final String address) // 当 XxlJobExecutor 被spring卸载时,会停止向admin server 注册|心跳 public void stopRegistry() // 向admin server 注册本地任务,并监听启动端口 public void start(final String address, final int port, final String appname, final String accessToken) // 停止客户端注册,心跳 public void stop() throws Exception
创建ExecutorBizImpl 对象,ExecutorBizImpl 里面封装了客户端对服务端通信交互(心跳,kill 任务,接收服务端处理,日志)
创建监听本地端口netty线程(守护线程)当创建的所有普通线程不再后,守护线程会自动结束(没有了可守护的线程)
在线程中向admin server 注册任务组 调用 startRegistry(appname, address);
调用 ExecutorRegistryThread.getInstance().start(appname, address);
创建一个守护线程向admin注册执行器
组装向admin 注册请求参数
public class RegistryParam{
private String registryGroup;// 注册组名,固定:EXECUTOR
private String registryKey; // 注册key,客户端配置文件中 appname
private String registryValue; // 注册的地址,配置文件中的ip,可不填,默认是当前客户端的ip
遍历adminBizList中的AdminBizClient,并调用AdminBizClient#registry(RegistryParam) api方法 向admin 注册任务组
每隔30秒,该线程会向admin重新发其注册请求,重复注册是客户端维护心跳一种方式,admin server 收到注册请求会首先 根据 EXECUTOR,appname,address 更新 xxl_job_registry 的 update_date。更新记录为0,则新增
TimeUnit.SECONDS.sleep(RegistryConfig.BEAT_TIMEOUT);
当循环注册的标识停止后,会再调用 AdminBizClient.registryRemove(registryParam) 移除当前任务组
并启动监听本地端口的消息,监听 admin server 向client 下发的消息