分布式任务

1991/6/26 面试分布式

# Java中定时任务

这里主要讲讲Java的定时任务是如何一步步发展而来的:

# 1、Timer

new Timer("testTimer").schedule(new TimerTask() {
    @Override
    public void run() {
        System.out.println("TimerTask");
    }
}, 1000,2000);
1
2
3
4
5
6

解释:1000ms是延迟启动时间,2000ms是定时任务周期,每2s执行一次

# 2、ScheduledExecutorService

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        System.out.println("ScheduledTask");
    }
}, 1, 1, TimeUnit.SECONDS);
1
2
3
4
5
6
7

解释:延迟1s启动,每隔1s执行一次,是前一个任务开始时就开始计算时间间隔,但是会等上一个任务结束在开始下一个

# 3、SpringTask

@Service
public class SpringTask {
    private static final Logger log = LoggerFactory.getLogger(SpringTask.class);

    @Scheduled(cron = "1/5 * * * * *")
    public void task1(){
        log.info("springtask 定时任务!");
    }
	
	@Scheduled(initialDelay = 1000,fixedRate = 1*1000)
    public void task2(){
        log.info("springtask 定时任务!");
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

解释:

  1. task1是每隔5s执行一次,{秒} {分} {时} {日期}
  2. task2是延迟1s,每隔1S执行一次

# 4、Quartz

quartz 是一个开源的分布式调度库,它基于java实现。

  1. Job 表示一个任务,要执行的具体内容。
  2. JobDetail 表示一个具体的可执行的调度程序,Job 是这个可执行程调度程序所要执行的内容,另外 JobDetail 还包含了这个任务调度的方案和策略。
  3. Trigger 代表一个调度参数的配置,什么时候去调。
  4. Scheduler 代表一个调度容器,一个调度容器中可以注册多个 JobDetail 和 Trigger。当 Trigger 与 JobDetail 组合,就可以被 Scheduler 容器调度了。
//创建调度器Schedule
SchedulerFactory schedulerFactory = new StdSchedulerFactory();
Scheduler scheduler = schedulerFactory.getScheduler();
//创建JobDetail实例,并与HelloWordlJob类绑定
JobDetail jobDetail = JobBuilder.newJob(HelloWorldJob.class).withIdentity("job1", "jobGroup1")
        .build();
//创建触发器Trigger实例(立即执行,每隔1S执行一次)
Trigger trigger = TriggerBuilder.newTrigger()
        .withIdentity("trigger1", "triggerGroup1")
        .startNow()
        .withSchedule(SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(1).repeatForever())
        .build();
//开始执行
scheduler.scheduleJob(jobDetail, trigger);
scheduler.start();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 常见的JOB实现方案

基于上面Java任务演化出分布式Job方案:

# 1、quartz

JDBCJobStore 支持集群所有触发器和job都存储在数据库中无论服务器停止和重启都可以恢复任务同时支持事务处理。

# 2、elastic-job

elastic-job 是由当当网基于quartz 二次开发之后的分布式调度解决方案 , 由两个相对独立的子项目Elastic-Job-Lite和Elastic-Job-Cloud组成 。

Elastic-Job-Lite定位为轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务。

Elastic-Job-Cloud使用Mesos + Docker(TBD)的解决方案,额外提供资源治理、应用分发以及进程隔离等服务

亮点:

  1. 基于quartz 定时任务框架为基础的,因此具备quartz的大部分功能
  2. 使用zookeeper做协调,调度中心,更加轻量级
  3. 支持任务的分片
  4. 支持弹性扩容 , 可以水平扩展 , 当任务再次运行时,会检查当前的服务器数量,重新分片,分片结束之后才会继续执行任务
  5. 失效转移,容错处理,当一台调度服务器宕机或者跟zookeeper断开连接之后,会立即停止作业,然后再去寻找其他空闲的调度服务器,来运行剩余的任务
  6. 提供运维界面,可以管理作业和注册中心。

# 3、xxl-job

个轻量级分布式任务调度框架 ,主要分为 调度中心和执行器两部分 , 调度中心在启动初始化的时候,会默认生成执行器的RPC代理

对象(http协议调用), 执行器项目启动之后, 调度中心在触发定时器之后通过jobHandle 来调用执行器项目里面的代码,核心功能和elastic-job差不多