二次封裝elastic-job-lite

1、概述

什麼是elastic-job-lite,它是定位爲輕量級無中心化解決方案,使用jar包的形式提供分佈式任務的協調服務,具體可以點擊鏈接進入官網Elastic-Job-Lite查看,本文主要使用elastic-job-lite和spring進行二次封裝,搭建自己的分佈式定時任務程序。設計思路是利用spring的自動裝載和ApplicationListener特性,在運行時掃描註冊相關標註爲Job註解類。

2、引入包名

<!--Spring 相關--->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!--elastic-job--->
<dependency>
    <groupId>com.dangdang</groupId>
    <artifactId>elastic-job-lite-spring</artifactId>
</dependency>

3、定義註解

定義一個接口或類註解該註解,運行時掃描所有使用該註解的接口或方法。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Component
public @interface ElasticScheduledJob {

    /**
     * cron 表達式
     */
    String cron();

}

4、定義抽象類

繼承elastic-job中的SimpleJob,擴展兩個方法,方便繼承類使用。

public abstract class AbsSingleJob implements SimpleJob {
    protected final Logger log = LoggerFactory.getLogger(getClass());

    @Override
    public void execute(ShardingContext shardingContext) {
        String name = getClass().getSimpleName();
        long startTime = System.currentTimeMillis();
        try {
            log.info("Job {} execute start, sharding context = {}", name, shardingContext);
            process(shardingContext);
            log.info("Job {} execute finish after {}ms", name, System.currentTimeMillis() - startTime);
        } catch (Exception e) {
            log.error("Job " + name + " error occur", e);
            handleException();
        }
    }

    /**
     * 捕獲異常(需要處理異常可重載handleException方法)和記錄執行日誌
     */
    protected void handleException() {

    }

    /**
     * 業務邏輯在這裏實現
     */
    protected abstract void process(ShardingContext shardingContext);
}

5、註冊Job

  • 註冊

啓動時從 ApplicationContext 中掃描 scheduler,對所有標註ElasticScheduledJob類進行掃描並進行註冊

/**
 * 加載所有job, 從 ApplicationContext 中掃描 scheduler
 */
private void initialize(ConfigurableApplicationContext applicationContext) {
    // 掃描註解ElasticScheduledJob的類
    for (Object bean : applicationContext.getBeansWithAnnotation(ElasticScheduledJob.class).values()) {
        Class<?> targetClass = AopProxyUtils.ultimateTargetClass(bean);
        ElasticScheduledJob annotation = AnnotationUtils.findAnnotation(targetClass, ElasticScheduledJob.class);

        if (annotation != null) {
            // 獲取job配置
            JobConfig jobConfig = JobConfig.newSingle(annotation.cron(), (AbsSingleJob) bean);
            JobScheduler scheduler = buildScheduler(jobConfig);
            scheduler.init();// 初始化
            applicationContext.getBeanFactory().registerSingleton(targetClass.getCanonicalName() + "Scheduler", scheduler);
        }
    }
}
  • 創建任務
private JobScheduler buildScheduler(JobConfig jobConfig) {
    return NewJobBuilder.newJobBuilder()
            .setRegCenter(registryCenter)
            .build(jobConfig);
}
  • 構建JobScheduler
public JobScheduler build(JobConfig jobConfig) {
    // 創建job配置
    LiteJobConfiguration jobConfiguration = createJobConfiguration(checkJobConfig(jobConfig));
    // 註冊監聽
    ElasticJobListener[] l;
    if (listeners != null) {
        l = new ElasticJobListener[listeners.getListeners().size()];
        listeners.getListeners().toArray(l);
    } else {
        l = new ElasticJobListener[0];
    }
    // 不使用作業事件監聽器
    if (jobEventConfiguration == null) {
        return jobConfig.getElasticJob() != null
                ? new SpringJobScheduler(jobConfig.getElasticJob(), regCenter, jobConfiguration)
                : new JobScheduler(regCenter, jobConfiguration, l);
    }
    // 使用作業事件監聽器
    return jobConfig.getElasticJob() != null
            ? new SpringJobScheduler(jobConfig.getElasticJob(), regCenter, jobConfiguration, jobEventConfiguration)
            : new JobScheduler(regCenter, jobConfiguration, jobEventConfiguration, l);
}

6、使用

使用方式很簡單,直接繼承AbsSingleJob,重寫相關方法,並類加入@ElasticScheduledJob註解即可。

@ElasticScheduledJob(cron = "0/2 * * * * ? * ")
public class CsgoBattleJob extends AbsSingleJob {

    @Override
    protected void process(ShardingContext shardingContext) {
        // 定時任務業務邏輯
    }
}

elastic-job-lite二次封裝核心內容上面已經介紹完,具體代碼可以到github查看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章