對於分佈式Job的思考


引言

在清理Github的時候,發現之前寫的一個簡單的分佈式任務分發系統ClawHub/task-distribution,使用了zk的選主與隊列,調度器使用spring的ThreadPoolTaskScheduler,任務支持cron表達式。html

這讓我想起在這以前還封裝過Quartz,那時候作的是單機版超大型應用,內部須要作調度系統。java

目前在公司使用過Elastic-Job,也使用過Spring自帶調度與ZK的結合,還有公司Boss系統提供的配置版本任務調度。git

寫這篇文章主要是簡單的回憶一下Quartz與Spring的ThreadPoolTaskScheduler,還有Elastic-job。再寫一下本身對分佈式Job的思考。github

一、quartz

官網地址:quartz-scheduler.orgspring

1.一、簡單使用

maven的pom文件:架構

<dependency>
    <groupId>org.quartz-scheduler</groupId>
    <artifactId>quartz</artifactId>
    <version>2.3.2</version>
</dependency>

具體任務:dom

import org.quartz.Job;
import org.quartz.JobExecutionContext;

import java.time.LocalDateTime;
import java.util.Random;

public class HelloJob implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        System.out.println(jobExecutionContext.getJobDetail().getJobDataMap().get("jobDetailJobData1"));
        System.out.println(jobExecutionContext.getTrigger().getJobDataMap().get("triggerJobData1"));
        System.out.println("HelloJob start at:"   LocalDateTime.now()   ", prints: Hello Job-"   new Random().nextInt(100));
    }
}

主調度器:maven

import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.concurrent.TimeUnit;

public class MainScheduler {
    public static void main(String[] args) throws SchedulerException, InterruptedException {
        // 一、建立調度器Scheduler
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        Scheduler scheduler = schedulerFactory.getScheduler();
        // 二、建立JobDetail實例,並與PrintWordsJob類綁定(Job執行內容)
        JobDetail jobDetail = JobBuilder.newJob(HelloJob.class).usingJobData("jobDetailJobData1", "測試JobDetail上下文")
                .withIdentity("job1", "group1").build();
        // 三、構建Trigger實例,每隔1s執行一次
        Trigger trigger = TriggerBuilder.newTrigger().usingJobData("triggerJobData1", "測試Trigger上下文")
                .withIdentity("trigger1", "triggerGroup1")
                .startNow()//當即生效
                .withSchedule(SimpleScheduleBuilder.simpleSchedule()
                        .withIntervalInSeconds(1)//每隔1s執行一次
                        .repeatForever()).build();//一直執行

        //四、執行
        scheduler.scheduleJob(jobDetail, trigger);
        System.out.println("--------MainScheduler start ! ------------");
        scheduler.start();

        //睡眠
        TimeUnit.MINUTES.sleep(1);
        scheduler.shutdown();
        System.out.println("--------MainScheduler shutdown ! ------------");
    }
}

通過上面三步,執行main方法,就能夠簡單的實現調度任務了,下面分別介紹出現的角色。分佈式

1.二、角色介紹

1.2.一、Job和JobDetail

Job是Quartz中的任務模板,JobDetail是Job的描述,當Scheduler執行任務的時候,會根據JobDetail建立新的Job,用過以後就釋放掉。ide

1.2.二、Trigger

觸發器,描述了任務是何時觸發執行,經常使用有SimpleTrigger、CronTrigger,cron表達式很是強大,基本上都是基於CronTrigger來作任務調度。

1.2.三、JobDataMap與JobExecutionContext

JobExecutionContext任務執行的上下文,JobDataMap保存上下文傳輸的數據。

1.一、架構原理

quartz架構.png 上面這幅圖能夠簡單的描述Quartz核心對象之間的關係。

二、Spring的ThreadPoolTaskScheduler

底層依賴於JUC的java.util.concurrent.ScheduledExecutorService。

2.一、簡單使用

import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;

import java.time.LocalDateTime;
import java.util.Random;

public class Main {
    public static void main(String[] args) {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(10);
        scheduler.initialize();
        scheduler.schedule(() -> {
            System.out.println("HelloJob start at:"   LocalDateTime.now()   ", prints: Hello Job-"   new Random().nextInt(100));
        }, new CronTrigger("0/1 * * * * ?"));
    }
}

三、Elastic-Job

Elastic-Job是一個分佈式調度解決方案,由兩個相互獨立的子項目Elastic-Job-Lite和Elastic-Job-Cloud組成。 官網:elasticjob.io

咱們使用的是輕量級的使用方案:elasticjob/elastic-job-lite

官方架構圖: elastic_job_lite.png 做業執行流程圖: job_exec.jpg

我也只有使用經驗,並無深刻的瞭解其原理,具體請參考官方文檔。

四、對於分佈式Job的思考

如今的Quartz也有集羣版本,我尚未接觸過,如今碰到的基本上都是基於Quartz的包裝,好比Elastic-Jobxxl jobazkaban

由於如今的項目基本都爲分佈式系統,因此對於調度系統而言,單機已經不怎麼適用了。

而對於分佈式調度系統,必然也有不少要求,下面講一下個人理解:

  • 任務定時完成 這個式調度系統的基本要求。
  • 任務可分片 對於一些大量數據的定時任務,若是隻在一臺機器上執行是很吃力的,因此應該有任務分片執行的功能,將大任務拆分到多個系統上執行。
  • 彈性擴容縮容 在增長或者減小節點時,任務可以自動均衡。
  • 任務可配置 任務的信息可動態配置。
  • 任務動態操做 任務動態地啓動、暫停、終止、刪除等。
  • 去中心化 任務的執行與否由各個節點本身控制,可是要保證任務執行不可重複。
  • 故障轉移 節點發生故障時,任務自動轉移。
  • 任務執行記錄 任務的執行信息須要有記錄。

能想到這隻有這麼多,感受Elastic-Job就很好用。

tencent.jpg

相關文章
相關標籤/搜索