【定时任务】定时任务技术实现原理和选型分析
定时任务的背景
在业务开发中,一定会遇到比如每天9点发送一个邮件,30分钟超时订单自动取消等 业务场景,一般都需要使用定时任务来解决,不同的语言也都提供了对应的内置定时任务。
其实如果对于一个单机实例来说,直接启动一个任务执行执行完成,这没有什么问题,但是在多实例分布式下,实例A 和 实例B 都是用单机定时任务,那么就会出现重复执行的场景。
我接触到的有一种解决方案,那就是通过redis 分布式锁的方式,避免重复执行,有多个实例,谁先抢到锁,谁去执行。
本质 其实通过一个分布式互斥资源 保证 谁获取到谁执行,那么mysql zk等都可以实现。
只不过这种方式需要自己去维护多个实例的是否要执行的状态。
定时任务选型
目前业界比较主流的方案单机任务和分布任务,对于单机版本 大多数都是用Spring,通过cron表达式。Kafka 和 netty 提供了另外一个思路就是通过时间轮机制,这种方式可以更高效率的管理和执行任务,避免JDK的定时任务 堆型的O(N)的时间复杂度
Netty时间轮实践与源码解析
分布式定时调度任务
如果只是简单的几个定时任务,仅仅使用多实例+锁的方式就可以满足,但是对于一个业务线来说,可能有很多定时任务,需要可视化的管理。所以就需要包含
1.任务的管理:创建,编辑、删除、查看等
2.任务的启动:启动,停止,重启
3.任务的调度的历史记录,执行情况等。
这样的话就可以很方便的管理定时调度任务。但是当任务过多的时候,就需要采用分布式多实例的部署,以及数据分片机制的管理。
数据分片机制
说白了就是当一个任务需要执行多少数据,A实例执行一部分,B实例执行一部分。提升系统的并发度。
Quartz
Quartz基于数据库来实现任务的分配。
核心原理是 每个阶段默认20S会查询数据库的QRTZ_TRIGGERS,不断获取并和其他节点抢占triiger,一旦获取triiger的控制权,本次任务就由调度器执行。
XXL-JOB
XXL-JOB的核心是将调度抽象成一个调度中心,将任务的调度和执行进行分离,类似存算分离的思想,这样职责上更单一和清晰。