基于SpringBoot的分布式定时器Elastic-Job注解化改造(懒人版)

分布式定时器elastic-job注解化使用改造(懒人版)

  • Elastic-Job介绍
  • 功能介绍
  • 实现步骤
    • 实现JobLinstener
    • 实现注册中心配置类
    • 注解类实现
    • SimpleJob配置类实现
    • Job类
  • 当前功能的缺憾
  • 要点总结
  • 改进建议

Elastic-Job介绍

Elastic-Job是当当开源的一个分布式定时框架框架,由Elastic-Job-Lite和Elastic-Job-Cloud组成。Elastic-Job-Lite是轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务;Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能,这里主要介绍使用的是Elastic-Job-Lite。

功能介绍

基于SpringBoot的分布式定时器Elastic-Job注解化改造(懒人版)_第1张图片
这是一张来自Elastic-Job官网的截图,好处是巴拉巴拉巴拉一大堆,我最看好的功能:支持并行调度,失效转移。我觉得也是这个框架的两大亮点。

实现步骤

实现JobLinstener

@Slf4j
public class JobListener implements ElasticJobListener {

    private long beginTime = 0;
    @Override
    public void beforeJobExecuted(ShardingContexts shardingContexts) {
        beginTime = System.currentTimeMillis();
        log.info("===>{} JOB BEGIN TIME: {} <===",shardingContexts.getJobName(), DateTime.now().toString());
    }

    @Override
    public void afterJobExecuted(ShardingContexts shardingContexts) {
    	long endTime = System.currentTimeMillis();
        log.info("===>{}, JOB END TIME: {},TOTAL CAST: {},current params:{} <===",shardingContexts.getJobName(),
                DateTime.now().toString(), endTime - beginTime,shardingContexts.getJobParameter());
    }
}

JobListener用于实现定时器执行前后的状态监控和时间统计

实现注册中心配置类

@Configuration
@ConditionalOnExpression("'${regCenter.serverList}'.length() > 0")
public class ElasticRegCenterConfig {

	@Bean(initMethod = "init")
	public ZookeeperRegistryCenter regCenter(
			@Value("${regCenter.serverList}") final String serverList,
			@Value("${regCenter.namespace}") final String namespace) {
		return new ZookeeperRegistryCenter(new ZookeeperConfiguration(
				serverList, namespace));
	}
}

这里注册中心选择了ZK,配置信息从配置文件中读取。

注解类实现

@Inherited
@Documented
@Retention(value=RetentionPolicy.RUNTIME)
@Target(value=ElementType.TYPE)
public @interface ElasticJobConfig {
	@AliasFor("value") String cron() default "";
	@AliasFor("cron") String value() default "";
	int shardingTotalCount() default 1;
	String shardingItemParameters() default "0=0";
}

添加一个注解类用于标注哪些类是Job类当前这个注解类,只支持SimpleJob类型,如果需要扩展可以自行添加注解属性。

SimpleJob配置类实现

@Configuration
@Slf4j
public class SimpleJobConfig {

	@Autowired
	private ZookeeperRegistryCenter regCenter;
	
	@Autowired
	private ApplicationContext applicationContext;


	
    @PostConstruct
    public void startSimpleJob(){
    	applicationContext.getBeansWithAnnotation(ElasticJobConfig.class).forEach((className,obj)->{
    		ElasticJobConfig config =  obj.getClass().getAnnotation(ElasticJobConfig.class);
			String cron = StringUtils.defaultIfBlank(config.cron(), config.value());
    		int shardingTotalCount = config.shardingTotalCount();
    		String shardingItemParameters= config.shardingItemParameters();
    		JobListener elasticJobListener = new JobListener();
    		SimpleJob simpleJob = (SimpleJob) obj;
    		new SpringJobScheduler(simpleJob, regCenter,
    				getLiteJobConfiguration(simpleJob.getClass(), cron,
    						shardingTotalCount, shardingItemParameters),
    						elasticJobListener).init();
		 });
    }
	

	private LiteJobConfiguration getLiteJobConfiguration(
			final Class<? extends SimpleJob> jobClass, final String cron,
			final int shardingTotalCount, final String shardingItemParameters) {
		return LiteJobConfiguration
				.newBuilder(
                        new SimpleJobConfiguration(JobCoreConfiguration
                                .newBuilder(jobClass.getName(), cron,
                                        shardingTotalCount)
                                .shardingItemParameters(shardingItemParameters)
                                .build(), jobClass.getCanonicalName()))
				.overwrite(true).build();
	}
}

这里提供了SimpleJob类型的定时任务实现方式,其他类型可以相似实现。

Job类

这里要说明一下为什么是懒人版了,这个项目只有我一个人负责,而我解决了基本需求之后就没动力继续改进了,如果哪位大牛提供完美的注解支持,望请告知一下。
贴一个通过注解实现的Job类的片段

@ElasticJobConfig(cron="*/2 * * * * ?",
        shardingTotalCount = 3,
		shardingItemParameters = "0=GPS,1=BDS,2=GLONASS")
@Component
@Slf4j
public class ClockErrorTask implements SimpleJob {

    @Override
    public void execute(ShardingContext shardingContext) {
       dosomthing();
    }
}

当前功能的缺憾

  • Job类还是必须实现SimpleJob

要点总结

下面开始要点总结:

  1. 通过以上代码可以实现SpringBoot通过注解运行Elastic-Job,当然缺点也是很明显必须实现SimpleJob接口

改进建议

  1. 修改注解对象为方法体
  2. 通过反射的方式在项目启动时动态注入Job可以改进代码

你可能感兴趣的:(SpringBoot)