Elastic-Job是当当开源的一个分布式定时框架框架,由Elastic-Job-Lite和Elastic-Job-Cloud组成。Elastic-Job-Lite是轻量级无中心化解决方案,使用jar包的形式提供分布式任务的协调服务;Elastic-Job-Cloud采用自研Mesos Framework的解决方案,额外提供资源治理、应用分发以及进程隔离等功能,这里主要介绍使用的是Elastic-Job-Lite。
这是一张来自Elastic-Job官网的截图,好处是巴拉巴拉巴拉一大堆,我最看好的功能:支持并行调度,失效转移。我觉得也是这个框架的两大亮点。
@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类型,如果需要扩展可以自行添加注解属性。
@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类的片段
@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();
}
}
下面开始要点总结: