大家好,我是 jack xu,今天和大家分享一下 xxl-job,xxl 是许雪里大神名字的首字母缩写,他是大众点评的程序员,也是利用业余时间创作的一个开源的任务调度系统。除了 xxl-job 之外,作者还开源了许多其他组件,现在一共有11个开源项目,组成了 xxl 家族。到目前为止在 xxl-job 官网上登记使用的公司有几百家,其实很多都没有登记,所以真正在使用的远不止这几百家,最新发布版本是:2.2.0。
在介绍 xxl-job 之前先介绍一下 Quartz,Quartz 有差不多20年的历史,调度模型已经非常成熟了,而且很容易集成到 Spring 中去,用来执行业务是一个很好的选择。但是它也面临着一些问题,比如:
1、调度逻辑(Scheduler)和任务类耦合在同一个项目中,随着调度任务数量逐渐增多,同时调度任务逻辑逐渐加重,调度系统的整体性能会受到很大的影响;
2、Quartz 集群的节点之间负载结果是随机的,谁抢到了数据库锁就由谁去执行任务,这就有可能出现旱的旱死,涝的涝死的情况,发挥不了机器的性能。
3、Quartz 本身没有提供动态调度和管理界面的功能,需要自己根据API进行开发。
4、Quartz 的日志记录、数据统计、监控不是特别完善。
xxl-job 和 elastic-job 都是对 Quartz 进行了封装,对上面这些问题进行了改进,让我们用起来更简单,功能更强大。
跟老牌的 Quartz 相比,xxl-job 拥有更加丰富的功能。
总体上可以分成三类:
1、性能的提升:可以调度更多任务。
2、可靠性的提升:任务超时、失败、故障转移的处理。
3、运维更加便捷:提供操作界面、有用户权限、详细的日志、提供通知配置、自动生成报表等等。
下面是官网 xxl-job 的架构图,没有找到最新的,是一张 V2.1.0 的图,但是大差不差,右下角红框标出来的自研 RPC(xxl-rpc),在 V2.2.0 里面已经替换成了 restful 风格的 http 请求方式。
我把上面的图精简了一下,xxl-job 的调度器和业务执行是独立的。调度器决定任务的调度,并且通过 http 的方式调用执行器接口执行任务。
下载地址:https://github.com/xuxueli/xxl-job
注意
不要 clone 最新的 master 分支代码,master 是正在开发的,应该点击 Releases 进入发布页面下载稳定版本(2.2.0),下载下来的源码如下:
数据库脚本在 doc/db 目录下:
将这个sql在本地执行一下,执行完以后会生成8张表,它们的作用分别如下:
表名 | 作用 |
---|---|
xxl_job_group | 执行器信息表:维护任务执行器信息 |
xxl_job_info | 调度扩展信息表:用于保存xxl-job调度任务的扩展信息,如任务分组、任务名、机器地址、执行器、执行入参和报警邮件等等 |
xxl_job_lock | 任务调度锁表 |
xxl_job_log | 调度日志表:用于保存xxl-job调度任务的历史信息,如调度结果、执行结果、调度入参、调度机器和执行器等等 |
xxl_job_log_report | 调度日志报表:用户存储xxl-job任务调度日志的报表,调度中心报表功能页面会用到 |
xxl_job_logglue | 任务GLUE日志:用于保存GLUE更新历史,用于支持GLUE的版本回溯功能 |
xxl_job_registry | 执行器注册表,维护在线的执行器和调度中心机器地址信息 |
xxl_job_user | 系统用户表 |
上文介绍过 xxl-job 的架构体系,分为调度中心和执行器,下载下来的源码是把这两个放一起的,admin 和executor 的项目可以单独复制出来(两个spring boot工程),修改一下 pom 文件。实际上开发、运行的时候肯定也是独立的工程。
然后是修改配置文件application.properties里的值,主要是端口、数据库的配置
### xxl-job, datasource
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
显式的加上登录调度中心的账号密码
xxl.job.login.username=admin
xxl.job.login.password=123456
好,然后启动项目,spirng boot 项目应该大家都会启动的哈,输入自己设置的账号密码
登录,搞定!
为了保证可用性,调度中心可用做集群部署,需要满足几个条件:
执行器相当于是小组组长,负责任务的具体执行,由它分配线程(组员)执行任务。执行器需要注册到调度中心,这样调度中心才知道怎样选择执行器,或者说做路由。执行器的执行结果,也需要通过回调的方式告诉调度中心。
在源码的 xxl-job-executor-samples 里有6个执行的 demo,告诉你怎么在一些主流框架里面创建执行器,没有框架也可以。执行器可以是一个单独的项目,也可以集成在业务项目里面(多启动一个端口),所以还有个名字叫业务实例。
这里选择 spring boot 项目用来举例子,从源码中单独拷一个项目出来,如果你是在业务项目里集成的话,也是参考这个 sample,在项目里加上 xxl-job-core 的依赖,添加配置就可以创建执行器了。
同样修改配置文件 application.properties,主要修改如下几个:
### 注册到调度中心
xxl.job.admin.addresses=http://127.0.0.1:7391/xxl-job-admin
### 日志存放路径
xxl.job.executor.logpath=D:/xxl-job/jobhandler
### 因为我们要模拟执行器集群部署,打包后单击运行多次,为服务设置随机端口
server.port=${random.int[10000,19999]}
### 执行器的端口
xxl.job.executor.port=${random.int[9000,10000]}
### 集群部署,这两项配置要一致
xxl.job.executor.appname=xxl-job-executor-jackxu
xxl.job.executor.address=
启动项目,在本地启动多个执行器集群的时候这里要打上勾,因为我们配置了随机端口,所以是不会报错的。
最后我们在调度中心-执行器管理里新增一个执行器
刷新一下,我这里启动的两个执行器都已经注册上来了
至此 xxl-job 已经安装完毕,下面我们就来创建一个任务测试一下
这里我新建了一个 SimpleJobHandler
新建任务有几个注意点:
1、在Spring Bean 实例中(@Component 注解),开发 Job 方法。方法格式要求为"public ReturnT < String > demoJobHandler(String param)",返回值和参数格式是固定的,这个是不能动的,唯一能动的是方法名。
2、在方法名上打上 @XxlJob 注解,这里面有几个属性,第一个 value 值对应的是调度中心新建任务的JobHandler
属性的值。另外的 init 对应 JobHandler 初始化方法,destory 对应 JobHandler 销毁方法。这两个方法要在任务类里面创建。
3、执行日志:需要通过"XxlJobLogger.log"打印执行日志,会写到指定的日志文件中。
这个是固定规范,任何任务的开发都要执行这个规范,还有上面代码上的开发步骤,这个是许雪里大神在源码中写的,我把它拷了过来,大家可以看下!
我们把上面写的代码在调度中心中配置一下,在任务管理-新增一个,里面有一些选项大家不知道是什么意思,这个没关系,后面我还会写一篇文章来介绍分片任务等功能,大家先按照我的配置配置一下。
点击启动
打开文件夹看下,路径就是我在 application.properties 里配的,任务是往日志里写5次 hello word 也写进去了
至此,大功告成,xxl-job 快速入门指南相信大家已经掌握了,大家可以按照我的教程做一遍,关于 xxl-job 的高级功能后面我还会再写一篇文章,原创不易,如果你觉得不错,请点一个赞!
xxl-job官网
https://www.xuxueli.com/xxl-job/
代码下载
https://github.com/xuxueli/xxl-job/