基本介绍
micro-job是一款轻量级的分布式任务执行框架,内部集成了quartz框架来完成任务的分布式调度,quartz是一个强大的任务执行框架,但是quartz为我们提供的功能却是有限,我们较为关心的执行日志采集、任务失败重试、任务权重调度等在原生的quartz框架内实现会较为麻烦。
架构设计模式
micro-job采用了server与node的概念进行编写。
server一般就是我们的业务端,是发起创建定时任务的模块,我们可以通过注入内置的JobExecuteService类进行对Job的基本操作。
node是任务执行的节点,是执行发起定时任务逻辑的模块,当server发起了任务后,会直接通过RPC框架的NIO协议通信给node,接收到任务执行的任务节点执行完成后将结果反馈给server。
具体在执行时选择的任务节点是什么,完全根据配置的负载执行策略。
最新版本说明
v0.0.1.RELEASE (2019-1-21发布)
任务上报
自动执行
ipHash负载执行策略
平滑轮询权重负载执行策略
随机权重负载执行策略
自动重连
心跳检查
任务重试
任务操作
任务上报
在node节点启动完成后会自动扫描本项目内实现JobTrigger接口的类,一同携带node节点的网络信息通过心跳的方式发送给server,server接收到后会将相应的信息进行持久化到数据库。
####自动执行
自动执行是指任务上报后就会自动执行任务,根据配置在JobTrigger实现类上的注解@Job内的autoStart属性进行决定的,如果该属性配置true并且通过cron属性配置了cron任务表达式,那么在任务上报完成后会自动在server通过JobExecuteService来进行启动任务。
ipHash负载执行策略
在micro-job内提供了三种负载执行策略,ip-hash是其中的一种,这种负载均衡策略一般在相同任务在多个执行node下才能够更好的提现出来,如果你的任务执行node较少,建议采用轮询权重策略。
该策略根据执行任务@Job配置属性的jobKey的hashCode值来自动就近分配。
在负载均衡选择执行node时会把jobKey所绑定的所有node的ip:port信息的hash值通过SortedMap进行排序处理,如果jobKey的hash值大于所有节点的最大值时,返回最大hash的任务执行node,否则通过tailMap返回就近的任务执行node。
平滑轮询权重负载执行策略
轮询权重负载策略在之前就被广大的应用,最大特点是可以根据权重任意配置某一个节点的执行的次数,你可以根据每一个node的承受压力的能力进行均衡配置。
如果相同jobKey的两个任务执行node策略配置相同,则会轮流执行。
权重可以通过@Job注解的weight属性进行配置,默认为:1
随机权重负载执行策略
这种策略其实跟ip-hash有一部分是差不多的
在初始化负载执行节点时,随机的权重会根据上一个节点权重+当前节点的权重作为新的权重值,然后通过最后放入集合节点的权重 * Math.random()方法进行获取随机权重值,通过tailMap返回的SortedMap的集合获取随机权重最近值的第一个作为本次随机出来的执行节点。
自动重连
重连有两种模式
node断开重连
如果node断开后,server会检查超过10秒未心跳检查的node的列表进行剔除,剔除时会自动断开与node的NIO连接。
当node发起第一次心跳检查时,又会自动的创建与node的NIO连接。
server断开重连
如果server断开后,node都会不停的重试与server连接,当server启动后收到node发起心跳请求后,server会将该node信息持久化到内存以及数据库。
心跳检查
心跳检查是一个server/node模式的基本设计,保持两端的心跳连接才能更好地进行通信,server在执行定时任务时至少在较短时间内保证node是有效的,当然也不能保证完全的node有效,所以我们才应该有了下面的任务重试机制
任务重试
任务重试场景比较多,下面是一个简单的场景:
任务执行时负载分配到了node1,如果node1这时停止了,或者出现了网络超时的问题,导致任务执行失败,这时任务JobTrigger.exexute方法就会返回JobExecuteResult.JOB_EXECUTE_RETRY,这时server得到反馈后就会写入重试的Queue内,然后通过线程自动读取Queue内等待重试的任务再次负载分配执行node进行执行,从而实现了任务重试机制。
任务操作
任务操作目前可以通过注入JobExecuteService类来进行,通过该类提供的对应的方法进行操作任务的启动、删除、暂停、判断是否存在等。
开始使用
micro-job已经上传到maven center中央仓库,所以我们可以通过maven、gradle等中央仓库支持的依赖方式就可以进行添加依赖。
工程依赖
这里是maven方式的依赖方式示例,如果你是其他方式,请访问spring-boot-starter-micro-job仓库地址,查看对应版本的依赖方式。
服务端依赖
com.gitee.hengboy
spring-boot-starter-micro-job-server
{lastVersion}
任务节点依赖
com.gitee.hengboy
spring-boot-starter-micro-job-node
{lastVersion}
依赖时建议采用最新的版本,把lastVersion更换为maven center内最新版本。
数据库初始化
我们通过集成quartz的JDBC方式进行封装,在quartz的基础表上进行了扩展,具体的表结构在项目的工程下的schema_mysql.sql文件内,这个脚本可以在MySQL、MariaDB数据库内直接执行,其他数据库版本待整理!
注意:v0.0.1.RELEASE版本目前使用项目的数据源进行操作任务相应的数据库表信息,暂时不支持单独的数据源。
常见问题
怎么修改执行策略?
可以通过修改@Job注解的strategy属性就行修改,该属性所属的值为LoadBalanceStrategy枚举实例。
怎么开启自动执行?
通过修改@Job注解的autoStart属性修改,配置true时任务上报后就会自动执行,默认为:false
JobKey生成的规则是什么?
JobKey默认使用@Job注解的jobKey属性,如果并未配置则使用配置@Job注解JobTrigger实现类的类名首字母小写来配置。
任务怎么动态删除?
目前有两种方式:
使用JobExecuteService的remove方法来根据jobKey进行删除
如果是在JobTrigger实现类内的execute方法内进行删除,直接return JobExecuteResult.JOB_EXECUTE_REMOVE;会在本次任务执行后删除。
任务重试次数怎么配置?
在server端的application.yml、application.properties文件内进行配置hengboy.job.server.retry-times参数的值即可,默认为:2
任务的重试次数怎么计算?
任务在执行的时,如果存在该任务绑定的执行node,并且本次执行并未成功就会被计入消耗1次重试次数,当然如果node执行后返回JobExecuteResult.JOB_EXECUTE_RETRY也不会计算次数。
支持一次性执行任务吗?
目前可以TriggerJob实现类方法execute通过JobExecuteResult.JOB_EXECUTE_REMOVE删除任务的方式来进行一次性执行。
更多问题请issuse
配置参数列表
server配置
hengboy:
job:
server:
heart-check-time: 5
retry-times: 5
heart-check-over-time: 10
reg-port: 9999
heart-check-time:心跳检查剔除间隔执行的时间,单位:秒,默认为:5秒
retry-times:配置任务重试的次数,超过重试次数会丢弃任务,默认为:2次
heart-check-over-time:心跳检查剔除的超时时长,单位:秒,如配置超时10秒后就会被剔除,默认为10秒
reg-port:server的监听的端口号,默认为9999
client 配置
hengboy:
job:
node:
local-port: 9997
reg-address: 192.168.1.75
reg-port: 9999
request-timeout: 5000
job-base-package: com.gitee.hengboy.job.node.demo
send-heart-sync-time: 5
send-heart-initial-delay: 5
local-port:node的端口号,该端口号会上报到server
reg-address:server的IP地址,默认为:127.0.0.1
reg-port:server的绑定端口号,默认为:9999
request-timeout:NIO执行超时时间,单位:毫秒,默认:5000毫秒
job-base-package:扫描JobTrigger实现类的base package,如果不配置则采用SpringBoot默认的base package
send-heart-sync-time:发送心跳检查的间隔执行事件,单位:秒,默认:5秒
send-heart-initial-delay:node启动后延时心跳的时间,单位:秒,默认:5秒
如果存在默认值的相关参数,无需在配置文件内配置。