,哈喽大家好啊,我是Hydra。,xxl–job是一款非常优秀的任务调度中间件,轻量级、使用简单、支持分布式等优点,让它广泛应用在我们的项目中,解决了不少定时任务的调度问题。,我们都知道,在使用过程中需要先到xxl-job的任务调度中心页面上,配置执行器executor和具体的任务job,这一过程如果项目中的定时任务数量不多还好说,如果任务多了的话还是挺费工夫的。,,假设项目中有上百个这样的定时任务,那么每个任务都需要走一遍绑定jobHander后端接口,填写cron表达式这个流程…,我就想问问,填多了谁能不迷糊?,于是出于功能优化(偷懒)这一动机,前几天我萌生了一个想法,有没有什么方法能够告别xxl-job的管理页面,能够让我不再需要到页面上去手动注册执行器和任务,实现让它们自动注册到调度中心呢。,分析一下,其实我们要做的很简单,只要在项目启动时主动注册executor和各个jobHandler到调度中心就可以了,流程如下:,,有的小伙伴们可能要问了,我在页面上创建执行器的时候,不是有一个选项叫做自动注册吗,为什么我们这里还要自己添加新执行器?,其实这里有个误区,这里的自动注册指的是会根据项目中配置的xxl.job.executor.appname
,将配置的机器地址自动注册到这个执行器的地址列表中。但是如果你之前没有手动创建过执行器,那么是不会给你自动添加一个新执行器到调度中心的。,既然有了想法咱们就直接开干,先到github上拉一份xxl-job的源码下来:,整个项目导入idea后,先看一下结构:,,结合着文档和代码,先梳理一下各个模块都是干什么的:,为了弄清楚注册和查询executor和jobHandler调用的是哪些接口,我们先从页面上去抓一个请求看看:,,好了,这样就能定位到xxl-job-admin模块中/jobgroup/save这个接口,接下来可以很容易地找到源码位置:,,按照这个思路,可以找到下面这几个关键接口:,但是如果直接调用这些接口,那么就会发现它会跳转到xxl-job-admin的的登录页面:,,其实想想也明白,出于安全性考虑,调度中心的接口也不可能允许裸调的。那么再回头看一下刚才页面上的请求就会发现,它在Headers中添加了一条名为XXL_JOB_LOGIN_IDENTITY的cookie:,,至于这条cookie,则是在通过用户名和密码调用调度中心的/login接口时返回的,在返回的response可以直接拿到。只要保存下来,并在之后每次请求时携带,就能够正常访问其他接口了。,到这里,我们需要的5个接口就基本准备齐了,接下来准备开始正式的改造工作。,我们改造的目的是实现一个starter,以后只要引入这个starter就能实现executor和jobHandler的自动注册,要引入的关键依赖有下面两个:,在调用调度中心的接口前,先把xxl-job-admin模块中的XxlJobInfo和XxlJobGroup这两个类拿到我们的starter项目中,用于接收接口调用的结果。,创建一个JobLoginService,在调用业务接口前,需要通过登录接口获取cookie,并在获取到cookie后,缓存到本地的Map中。,其他接口在调用时,直接从缓存中获取cookie,如果缓存中不存在则调用/login接口,为了避免这一过程失败,允许最多重试3次。,创建一个JobGroupService,根据appName和执行器名称title查询执行器列表:,我们在后面要根据配置文件中的appName和title判断当前执行器是否已经被注册到调度中心过,如果已经注册过那么则跳过,而/jobgroup/pageList接口是一个模糊查询接口,所以在查询列表的结果列表中,还需要再进行一次精确匹配。,注册新executor到调度中心:,创建一个JobInfoService,根据执行器id,jobHandler名称查询任务列表,和上面一样,也是模糊查询:,注册一个新任务,最终返回创建的新任务的id:,在创建任务时,必填字段除了执行器和jobHandler之外,还有任务描述、负责人、Cron表达式、调度类型、运行模式。在这里,我们默认调度类型为CRON、运行模式为BEAN,另外的3个字段的信息需要用户指定。,因此我们需要创建一个新注解@XxlRegister,来配合原生的@XxlJob注解进行使用,填写这几个字段的信息:,最后,额外添加了一个triggerStatus属性,表示任务的默认调度状态,0为停止状态,1为运行状态。,基本准备工作做完后,下面实现自动注册执行器和jobHandler的核心代码。核心类实现ApplicationListener接口,在接收到ApplicationReadyEvent事件后开始执行自动注册逻辑。,自动注册执行器的代码非常简单,根据配置文件中的appName和title精确匹配查看调度中心是否已有执行器被注册过了,如果存在则跳过,不存在则新注册一个:,自动注册任务的逻辑则相对复杂一些,需要完成:,具体代码如下:,创建一个配置类,用于扫描bean:,将它添加到META-INF/spring.factories文件:,到这里starter的编写就完成了,可以通过maven发布jar包到本地或者私服:,新建一个springboot项目,引入我们在上面打好的包:,在application.properties中配置xxl-job的信息,首先是原生的配置内容:,此外还要额外添加我们自己的starter要求的新配置内容:,完成后在代码中配置一下XxlJobSpringExecutor,然后在测试接口上添加原生@XxlJob注解和我们自定义的@XxlRegister注解:,启动项目,可以看到执行器自动注册成功:,,再打开调度中心的任务管理页面,可以看到同时添加了两个注解的任务也已经自动完成了注册:,,从页面上手动执行任务进行测试,可以执行成功:,,到这里,starter的编写和测试过程就算基本完成了,项目中引入后,以后也能省出更多的时间来摸鱼学习了~
© 版权声明
文章版权归作者所有,未经允许请勿转载。