Elastic-Job是当当网的任务调度开源框架,有以下功能
分布式调度协调 弹性扩容缩容 失效转移 错过执行作业重触发 作业分片一致性,保证同一分片在分布式环境中仅一个执行实例 自诊断并修复分布式不稳定造成的问题 支持并行调度 支持作业生命周期操作 丰富的作业类型 Spring整合以及命名空间提供 运维平台
具体信息可以查看 官网 ,Elastic-Job的文档很详细,同时也有相应的demo。但是,美中不足的是他的springboot版本的demo用的是xml结构的。网上的例子都有点乱,花了点时间整合了下,现在就开始吧。
快速入门
1.pom文件
<elastic-job.version>2.1.5</elastic-job.version> <dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-core</artifactId> <version>${elastic-job.version}</version> </dependency> <!-- elastic-job-lite-spring --> <dependency> <groupId>com.dangdang</groupId> <artifactId>elastic-job-lite-spring</artifactId> <version>${elastic-job.version}</version> </dependency>
2.定义zookeeper
@Configuration public class ElasticRegCenterConfig { /** * 配置zookeeper * @param serverList * @param namespace * @return */ @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)); } }
3.定义job
@Component public class SimpleJobDemo implements SimpleJob { @Override public void execute(ShardingContext shardingContext) { System.out.println(String.format("------Thread ID: %s, 任務總片數: %s, " + "当前分片項: %s.当前參數: %s," + "当前任務名稱: %s.当前任務參數: %s" , Thread.currentThread().getId(), shardingContext.getShardingTotalCount(), shardingContext.getShardingItem(), shardingContext.getShardingParameter(), shardingContext.getJobName(), shardingContext.getJobParameter() )); } }
4.定义任务监听器,统计每次任务执行的时间
public class MyElasticJobListener implements ElasticJobListener { private static final Logger logger = LoggerFactory.getLogger(MyElasticJobListener.class); private long beginTime = 0; @Override public void beforeJobExecuted(ShardingContexts shardingContexts) { beginTime = System.currentTimeMillis(); logger.info("===>{} JOB BEGIN TIME: {} <===",shardingContexts.getJobName(), TimeUtil.mill2Time(beginTime)); } @Override public void afterJobExecuted(ShardingContexts shardingContexts) { long endTime = System.currentTimeMillis(); logger.info("===>{} JOB END TIME: {},TOTAL CAST: {} <===",shardingContexts.getJobName(), TimeUtil.mill2Time(endTime), endTime - beginTime); } }
5.配置JobConfiuration,配置job随容器一起启动
按 Ctrl+C 复制代码
按 Ctrl+C 复制代码
配置文件如下
server.port=${random.int[10000,19999]} regCenter.serverList = localhoost:2181 regCenter.namespace = elastic-job-lite-springboot stockJob.cron = 0/5 * * * * ? stockJob.shardingTotalCount = 4 stockJob.shardingItemParameters = 0=0,1=1,2=0,3=1
启动项目,输出
大家可以仔细的观察下配置文件和输出的对应关系。假设我先有这样的需求。
定时任务在两台主机上A,B同时运行.A处理id是奇数的数据,B处理Id为偶数的数据
用传统的定时任务例如@Schedule注解能实现么?那当然是可以,直接写死硬编码即可。用Elastic-Job的话,则相当灵活,示例如下
public class DbQueryJob implements SimpleJob { @Autowired private XXXDao xxxDao; @Override public void execute(ShardingContext shardingContext) { String shardingParameter = shardingContext.getShardingParameter(); //mod是对id取余后的结果 List<xxx> xxxlists=xxxDao.select("select * from table where mod="+shardingParameter); xxxlists.forEach(x->{ System.out.println("参数:"+shardingContext.getShardingParameter()+"状态"+x.getStatus()); }); } }
稍微讲下原理
Elastic-Job默认采用平均分片策略
如果有3台服务器,分成9片,则每台服务器分到的分片是:1=[0,1,2], 2=[3,4,5], 3=[6,7,8] 如果有3台服务器,分成8片,则每台服务器分到的分片是:1=[0,1,6], 2=[2,3,7], 3=[4,5] 如果有3台服务器,分成10片,则每台服务器分到的分片是:1=[0,1,2,9], 2=[3,4,5], 3=[6,7,8]
上述配置文件我们分成4片,A服务分到0,1 B服务分到2,3,同时 shardingItemParameters 参数表明了每个分片对应的ItemParameters,所以A服务的 shardingContext.getShardingParameter()=0
通过这样的逻辑,我们就能实现我们的分片业务了。
以上,就是Springboot整合Elastic-Job
转载地址:https://www.cnblogs.com/xmzJava/p/9838358.html