一、什么是分布式定时任务
将一个任务拆分成多个独立的任务项(每个任务项也称为一个分片),由分布式的服务器分别执行某一个或多个分片任务项。
二、elastic-job主要特性
1.分布式调度协调,去中心化
2.弹性扩容缩容
3.失效转移
4.错过执行作业重触发
5.作业分片一致性,保证同一分片在分布式环境中仅一个执行实例
其他参考官网:https://shardingsphere.apache.org/elasticjob/legacy/lite-2.x/00-overview/
三、原理解析
1.与zookeeper底层通讯机制
1.1底层采用curator请求zookeeper,curator底层是采用原生的niosocket通讯,同时预留了netty支持。
1.2普通Socket和NioSocket的区别:
普通Socket是客户端发出一次请求、服务端接收到后响应、客户端接收到服务端的响应才能再次请求。
NioSocket是引入了三个概念:Channel、Selector、Buffer。Buffer是将很多请求打包,一次性发出去,有Selector扮演选择器的角色,将请求分转给对应的通道(Channel)进行处理响应。
2.弹性分布式实现
- 第一台服务器上线触发主服务器选举。主服务器一旦下线,则重新触发选举,选举过程中阻塞,只有主服务器选举完成,才会执行其他任务。
- 某作业服务器上线时会自动将服务器信息注册到注册中心,下线时会自动更新服务器状态。
- 主节点选举,服务器上下线,分片总数变更均更新重新分片标记。
- 定时任务触发时,如需重新分片,则通过主服务器分片,分片过程中阻塞,分片结束后才可执行任务。如分片过程中主服务器下线,则先选举主服务器,再分片。
- 通过上一项说明可知,为了维持作业运行时的稳定性,运行过程中只会标记分片状态,不会重新分片。分片仅可能发生在下次任务触发前。
- 每次分片都会按服务器IP排序,保证分片结果不会产生较大波动。
- 实现失效转移功能,在某台服务器执行完毕后主动抓取未分配的分片,并且在某台服务器下线后主动寻找可用的服务器执行任务。
3.启动流程
微服务启动时会执行主节点选举,服务器和任务信息注册;主节点主要作用是触发重新分片事件时,执行重新分片。
总体流程
详细启动流程(来源官网)
4.任务执行流程
总体流程:
quartz内部定时器定时触发,获取本机的分片任务,执行分片任务,内部实现采用内存缓存和监听zookeeper事件来维护主节点和分片信息。
详细流程(来源官网):
其他详细参考官网:https://shardingsphere.apache.org/elasticjob/legacy/lite-2.x/03-design/lite-design/
四、elastic-job与quartz
1.与quartz联系区别
elastic-job使用了quartz的调度机制,内部原理一致,他可以看作是quartz的一个扩展实现,使用注册中心(zookeeper)替换了quartz的jdbc数据存储方式,此外,elastic-job又支持分片等特殊功能
2.elastic-job对应quartz的三要素解析
Job | LiteJob.java |
Trigger | cron |
Scheduler | JobScheduler.java |
2.1 LiteJob 实现了quartz的Job接口
1 public final class LiteJob implements Job {
2
3 @Setter
4 private ElasticJob elasticJob;
5
6 @Setter
7 private JobFacade jobFacade;
8
9 @Override
10 public void execute(final JobExecutionContext context) throws JobExecutionException {
11 JobExecutorFactory.getJobExecutor(elasticJob, jobFacade).execute();
12 }
13 }
2.2 从JobScheduler.java的init()方法中初始化了这三要素
1 public void init() {
2 LiteJobConfiguration liteJobConfigFromRegCenter = schedulerFacade.updateJobConfiguration(liteJobConfig);
3 JobRegistry.getInstance().setCurrentShardingTotalCount(liteJobConfigFromRegCenter.getJobName(), liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getShardingTotalCount());
4 JobScheduleController jobScheduleController = new JobScheduleController(
5 createScheduler(), createJobDetail(liteJobConfigFromRegCenter.getTypeConfig().getJobClass()), liteJobConfigFromRegCenter.getJobName());
6 JobRegistry.getInstance().registerJob(liteJobConfigFromRegCenter.getJobName(), jobScheduleController, regCenter);
7 schedulerFacade.registerStartUpInfo(!liteJobConfigFromRegCenter.isDisabled());
8 jobScheduleController.scheduleJob(liteJobConfigFromRegCenter.getTypeConfig().getCoreConfig().getCron());
9 }
2.3 trigger在JobScheduleController.java创建
1 private CronTrigger createTrigger(final String cron) {
2 return TriggerBuilder.newTrigger().withIdentity(triggerIdentity).withSchedule(CronScheduleBuilder.cronSchedule(cron).withMisfireHandlingInstructionDoNothing()).build();
3 }
五、elastic-job其他优缺点
1.优点
无数据库瓶颈,性能高,任务数大且要求低延迟时,一般不需要做二次分发(只要划分更多的分片,分片粒度更细)
开源,已经过大量公司的实际使用,分布式定时任务框架中口碑较好
支持单独配置单个任务的策略配置
支持脚本任务
去中心化设计(主节点选举机制)
2.缺点:
zookeeper部署在有状态容器中会增加运维成本(或者可以先部署在非容器中)
和其他分布式定时任务对比:https://www.cnblogs.com/Windge/p/14127948.html
其他参考:
https://shardingsphere.apache.org/elasticjob/legacy/lite-2.x/00-overview/
https://www.cnblogs.com/davidwang456/p/10346013.html