xxl-job详细使用指南

11,722 阅读7分钟

新建任务说明

本篇文章承接上文《xxl-job快速入门指南》,上一次和大家简单介绍了下 xxl-job 的由来以及使用方法,本篇文章将会详细介绍一些高级使用方法及特性。

上文中我们在新建一个任务的时候发现有很多的选项,现在我们来详细聊一聊他们的作用。

路由策略

路由策略是指一个任务可以由多个执行器完成,那具体由哪一个完成呢,这就要看我们指定的路由策略了,这个参数当执行器做集群部署的时候才有意义。

Quartz中只能随机负载 那么这里的第一个,最后一个是按什么顺序来的呢,就是点击查看-注册节点中的1,2,3,4,第一个指的就是1,最后一个指的就是4。

运行模式

运行模式分为两种,一种是BEAN,一种是GLUE

  • BEAN模式:这个是在项目中写 Java 类,然后在 JobHandler 里填上 @XxlJob 里面的名字,是在执行器端编写的
  • GLUE模式:支持Java、Shell、Python、PHP、Nodejs、PowerShell,这个时候代码是直接维护在调度中心这边的

我这里新建了一个 GLUE(Java) 模式的任务,点击操作里面的 GLUE IDE 这里就可以编辑我们想要执行的代码了 但是这样会存在一个安全隐患的问题,没有做鉴权,方法也很简单,只需要在调度中心和执行器的application.properties 里加上相同的 token 即可。

xxl.job.accessToken=

阻塞处理策略

阻塞处理策略指的是任务的一次运行还没有结束,下一次调度的时间又到了,比如一个任务执行的时间是三分钟,但是设置的频率是每两分钟执行一次,这时候第一次还没执行完,第二次怎么办?

一共有三个选项,如下图:

子任务

当我们要写一个 Job 的时候,任务是相互依赖的。比如下面我要干这么多事情,A干完了干B,B干完了干C,C干完了干D。 解决这种问题的时候思路有两种。第一种是把这么多逻辑写成一个大 job,串行化。第二种就是用子任务,在一个任务末尾触发另一个任务。

如果我们需要在本任务执行结束并且执行成功的时候触发另外一个任务,那么就可以把另外的任务作为本任务的子任务执行,因为每个 Job 都有自己的唯一 id,所以只需在子任务一栏填上任务 id 即可。

任务超时时间

超时的意思就是如果在指定时间内没有返回结果,就不再等待结果。

高级任务用法

分片任务

假设我们有个任务需要处理20万条数据,每条数据的业务逻辑处理要0.1秒,对于普通任务单线程来讲,需要处理5.5个小时才能处理完。这时候你想要提高速度,你的第一反应就是开多线程跑嘛,我开3个,差不多就是一个多小时就能搞定了,你的思路完全正确!

这时候将会是下面这种情况,在执行器0上有三个线程在拼命的工作,但是这样大家觉得好不好?不好吧,我执行器0在这累的要死,你执行器1和执行器2在那休息,旱的旱死,涝的涝死,首先这是一个分配不均匀的问题。其次当执行器0三个线程都在工作的时候会浪费它的资源,使之这台服务器的性能也会下降,所以这是一种不好的方式。

这时候就要用到我们的分片任务了,真正好的方案如下,这是一个既科学又合理的方案。三台执行器各自起一个线程来共同把这个任务完成! 这时候有个问题,三台机器大家都执行同一段代码,那岂不是乱套了,这个数据你也执行一遍,我也执行一遍,它也执行一遍。 解决的思路很简单,一台执行器处理总数的1/3,大家把需要干的活平均分了嘛,我干1/3,你干1/3,它干1/3,这样也不会产生冲突。

分片任务在运行的时候,调度器会给每个执行器发送一个不同的分片序号,分片的最大序号跟执行器的总数量是一样的,确保每个执行器都会执行到这个任务,比如上图中第一个执行器拿到分片序号0,第二台执行器拿到分片序号1,第三台执行器拿到分片序号2。那现在就好办了,我们只需要把处理的数据进行模3取余,余数为0的数据就由执行器0干,余数为1的数据就由执行器1干,余数为2的数据就由执行器2干。

我们获取数据的sql可以这样写:

//count分片总数,index当前分片数
select id,name,password from student where status=0 and mod(id,#{count})=#{index} order by id desc limit 1000;

在代码中实现这样写 新建任务的时候选择分片广播,填上对应的JobHandler即可 最后需要说明一下,分片的数据量不一定是完全均等的数据量,上面的取模只是一个举例,一个思路。我们也可以把0、1、2替换成其他条件去从所有数据中获取部分数据,比如分片序号0的机器我查2018年的数据,分片序号1的机器我查2019年的数据,分片序号2的机器我查2020年的数据。具体怎么分全靠我们的业务来选择。

如果增加或者减少了节点,总分片数和最大分片序号会实时发生变化。

命令任务

命令任务比较有用,比如我们需要定时重启数据库(service restart),定时备份数据文件(cp tar rm),定时清理日志(rm)。

命令行的使用也很简单,只需要把执行的命令作为参数传递进来即可 现在我们来新建一个命令行任务 启动一下任务,每过5秒,这个计算器就自动弹出来了

周期性任务

周期性任务就是在任务的开始和销毁的时候执行自定义的方法,做一些自己想做的事

总结

小伙伴们,关于xxl-job的两篇教程到这边就要结束了,最后我在进行一下总结。

调度中心

负责管理调度信息,按照调度配置发出调度请求,自身不承担业务代码。调度系统与任务解耦,提高了系统可用性和稳定性,同时调度系统性能不再受限于任务模块;

调度中心支持可视化、简单且动态的管理调度信息,包括任务新建,更新,删除,GLUE开发和任务报警等,所有上述操作都会实时生效,同时支持监控调度结果以及执行日志,支持执行器Failover。

调度中心会把调度请求放进一个异步调度队列,理论上默认配置下的调度中心单机能够支撑5000任务并发并且稳定运行,但是由于受网络延迟、DB读写耗时不同、任务调度密集程度不同,会导致任务量上限会上下波动。如果需要支撑更多的任务量,可以通过调大调度线程数、降低调度中心与执行器ping延迟、提升机器配置等。

xxl.job.triggerpool.fast.max=200
xxl.job.triggerpool.slow.max=100

执行器

负责接收调度请求并执行任务逻辑,任务模块专注于任务的执行等操作,开发和维护更加简单和高效;

接收调度中心的执行请求、终止请求和日志请求等。

从整体来看,xxl-job架构依赖少,功能强大,简约而不简单,方便部署,易于使用。原创不易,觉得不错的话,请点一个赞