elastic-job源码浅析(任务执行过程)

1.启动过程流程图

启动过程

流程图详细地描述了各个作业细节的执行过程,看上去流程非常复杂,其主要的功能点为:判断作业是否可执行,判断作业是否分片执行,作业执行状态监听,作业失效转移等。下面我们结合代码一步步窥探他的执行过程。

2.核心源码分析

2.1 作业入口

/**
 * Elastic Job Lite提供的Quartz封装作业.
 *
 * @author zhangliang
 */
public class LiteJob implements Job {
    
    @Setter
    private ElasticJob elasticJob;
    
    @Override
    public void execute(final JobExecutionContext context) throws JobExecutionException {
        elasticJob.execute();
    }
}

LiteJob实现了Quartz的Job接口,并且持有elasticJob的实现类,通过代理的方式实现了ElasticJob与Quartz的无缝衔接;

【亮点】这是一种典型的代理模式,其好处在于体验上完全与Quartz的Job一致,并且遵循了代码的开闭原则,使得代码具有很好地拓展性:例如ElasticJob接口有SimpleJob,DataFlowJob或者用户自定义的多种实现类,因此具有很好地拓展性。

2.2 AbstractElasticJob抽象类及其原理

/**
 * 弹性化分布式作业的基类.
 * 
 * @author zhangliang
 * @author caohao
 */
@Slf4j
public abstract class AbstractElasticJob implements ElasticJob {
    
    //具体的业务实现放在jobFacade门面类中实现,简化代码复杂度
    private JobFacade jobFacade;
    
    @Override
    public final void execute() {
        log.trace("Elastic job: job execute begin.");
        //判断与注册中心时间差是否在允许范围内
        jobFacade.checkMaxTimeDiffSecondsTolerable();
        //获取分片上下文
        JobExecutionMultipleShardingContext shardingContext = jobFacade.getShardingContext();
        //若前面的任务仍在执行,则设置错过执行标记,延迟执行
        if (jobFacade.misfireIfNecessary(shardingContext.getShardingItems())) {
            log.debug("Elastic job: previous job is still running, new job will start after previous job completed. Misfired job had recorded.");
            return;
        }
        //清除作业上次执行的信息
        jobFacade.cleanPreviousExecutionInfo();
        try {
            //各监听器执行job执行前方法
            jobFacade.beforeJobExecuted(shardingContext);
            //CHECKSTYLE:OFF
        } catch (final Throwable cause) {
            //CHECKSTYLE:ON
            handleJobExecutionException(new JobException(cause));
        }
        //执行具体的job业务逻辑
        executeJobInternal(shardingContext);
        log.trace("Elastic job: execute normal completed, sharding context:{}.", shardingContext);
        while (jobFacade.isExecuteMisfired(shardingContext.getShardingItems())) {
            log.trace("Elastic job: execute misfired job, sharding context:{}.", shardingContext);
            jobFacade.clearMisfire(shardingContext.getShardingItems());
            executeJobInternal(shardingContext);
            log.trace("Elastic job: misfired job completed, sharding context:{}.", shardingContext);
        }
        //按需失效转移
        jobFacade.failoverIfNecessary();
        try {
            //执行监听后事件
            jobFacade.afterJobExecuted(shardingContext);
            //CHECKSTYLE:OFF
        } catch (final Throwable cause) {
            //CHECKSTYLE:ON
            handleJobExecutionException(new JobException(cause));
        }
        log.trace("Elastic job: execute all completed.");
    }
    
    private void executeJobInternal(final JobExecutionMultipleShardingContext shardingContext) {
        if (shardingContext.getShardingItems().isEmpty()) {
            log.trace("Elastic job: sharding item is empty, job execution context:{}.", shardingContext);
            return;
        }
        //注册任务执行信息
        jobFacade.registerJobBegin(shardingContext);
        try {
            executeJob(shardingContext);
        //CHECKSTYLE:OFF
        } catch (final Throwable cause) {
        //CHECKSTYLE:ON
            handleJobExecutionException(new JobException(cause));
        } finally {
            // TODO 考虑增加作业失败的状态,并且考虑如何处理作业失败的整体回路
            jobFacade.registerJobCompleted(shardingContext);
        }
    }
    
    protected abstract void executeJob(final JobExecutionMultipleShardingContext shardingContext);
    
    @Override
    public void handleJobExecutionException(final JobException jobException) {
        log.error("Elastic job: exception occur in job processing...", jobException.getCause());
    }
    
    @Override
    public final JobFacade getJobFacade() {
        return jobFacade;
    }
    
    @Override
    public final void setJobFacade(final JobFacade jobFacade) {
        this.jobFacade = jobFacade;
    }

【亮点】外观模式传送门
上面的代码中应用到了外观模式(Facade),AbstractElasticJob持有jobFacade对象,Elasticjob负责统筹整体的job执行流程但无需关注业务的具体实现,转而将复杂的业务处理逻辑交由jobFacade中的方法进行处理,从而将job与具体的业务逻辑抽离出来方便阅读和拓展。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,001评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,210评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,874评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,001评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,022评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,005评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,929评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,742评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,193评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,427评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,583评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,305评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,911评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,564评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,731评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,581评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,478评论 2 352

推荐阅读更多精彩内容

  • Quartz是一个完全由java编写的功能丰富的开源作业调度库,可以集成到几乎任何Java应用程序中,小到独立应用...
    ProteanBear阅读 7,060评论 3 24
  • 1.ios高性能编程 (1).内层 最小的内层平均值和峰值(2).耗电量 高效的算法和数据结构(3).初始化时...
    欧辰_OSR阅读 29,368评论 8 265
  • 源码阅读小技巧传送门 1.写在前面 elastic-job是当当开源的一款非常好用的作业框架,在此之前,任务调度的...
    飞盏阅读 1,372评论 0 0
  • 当懵懂的心逐渐清晰, 心中的梦终得以萌芽。 于是, 再也不会停下追逐的步伐。 哪怕, 它很小。 或许, 它很大! ...
    荔枝khy阅读 338评论 4 2
  • 一排排的白房子互相挤着条条青石路,他不知道自己在哪里,只身踏在青石路慢慢往前走,死一般的寂静告诉他这里就他一个人,...
    夏虫_不语冰阅读 204评论 1 3