定时任务应该是很多项目里面必备的一个组件,笔者公司里的项目也是一样,定时调度任务是用XXL-JOB(一个定时调度管理的框架,官方网站www.xuxueli.com/xxl-job/)来做的,今天笔者就来分享我对该框架的路由策略的一些分析见解。
1,调度界面
笔者用的XXL-JOB版本为2.0.2,调度界面如下图,路由策略一共有十个,分别是:第一个,最后一个,轮询,随机,一致性HASH,最不经常使用,最近最久未使用,故障转移,忙碌转移,分片广播。
2,执行器管理界面
路由策略就是从该执行器上注册了的OnLine机器地址里面按照某种规则选出一个或者多个服务器地址。
3,路由策略
3.1 路由策略枚举定义
所有的路由策略都是用枚举类Enum来定义的,便于管理和扩展,ExecutorRouteStrategyEnum.Java,代码结构如下图:
3.2 路由策略之第一个
顾名思义,该策略就是选取执行器管理的注册地址的第一个,利用List很好实现。
3.3 路由策略之最后一个
顾名思义,该策略就是选取执行器管理的注册地址的最后一个,利用List很好实现。
3.4 路由策略之轮询
顾名思义,该策略就是依次选取执行器管理的注册地址的一个,周而复始。
亮点:针对每一个唯一的任务会有一个唯一的jobId,在这里用可以一个静态的同步的Map来存储每个jobId和其对应的count,这样可以应对多个定时任务同时触发带来的数据一致性问题,同时也存储了所有调用了的任务的映射,每次++count之后,便对整个任务的注册地址的数量取余,作为注册地址列表的索引。从而实现了对每一个任务的轮询。如果超过24h没有触发调用的话,清空Map释放一定空间。
3.5 路由策略之随机
顾名思义,该策略就是随机选取执行器管理的注册地址的一个,利用Random很好实现。
3.6 路由策略之一致性HASH
顾名思义,该策略就是实现一个一致性HASH的负载均衡算法,名词解释定义可以参考
亮点:利用MD5加密jobId,并和0xffffffffL做与操作构成32位的HASH环;利用TreeMap和SortedMap来构造HASH环,关键方法是tailMap(K fromKey) 方法,用于返回此映射,其键大于或等于fromKey的部分映射;多嵌套一层虚拟节点以防止同一时间的调用的任务的过多压垮服务的情况。
3.7 路由策略之最不经常使用(LFU)
亮点:针对每一个唯一的任务会有一个唯一的jobId,在这里用可以一个静态的同步的Map来存储每个jobId和其对应的使用记录,这样可以应对多个定时任务同时触发带来的数据一致性问题,同时也存储了所有调用了的任务的映射。使用记录也用Map来存,存的是某个服务地址与其对应调用次数的映射,最后实现Comparator接口,重写compare方法根据调用次数排序。取的时候get0即可,调用完之后调用次数自增1。
3.8 路由策略之最近最久未使用(LRU)
LRU全称是Least Recently Used,即最近最久未使用的意思。 LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小。也就是说,当限定的空间已存满数据时,应当把最久没有被访问到的数据淘汰。
亮点:针对每一个唯一的任务会有一个唯一的jobId,在这里用可以一个静态的同步的Map来存储每个jobId和其对应的最近使用记录,这样可以应对多个定时任务同时触发带来的数据一致性问题,同时也存储了所有调用了的任务的映射。在构造LinkedHashMap的时候设置accessOrder属性为true,实现LRU。
3.9 路由策略之故障转移
3.10 路由策略之忙碌转移
3.11 路由策略之分片广播
顾名思义,该策略就是选取执行器管理的注册地址,每一个地址都执行一次,可以类比于MQ的广播模式。
亮点:这块的逻辑没有写在strategy包下,而是单独拎出来的逻辑。