分布式定时任务Elastic Job使用实践
项目因为要分布式部署,所以调研了Elastic Job这个插件,功能很强大,但也有不足的地方有bug,希望作者不断的更新下去。
经过几天的研究,基本使跑起来了,两台pc机,192.168.3.131(跑个两个tomcat),想当于这个机器跑了两个job实例,192.168.3.103(跑了一个tomcat),Elastic Job并没有处理数据分片的功能,数据分片需要用户自己实现。
通过Elastic Job控制台可以很清楚明了的看到当前机器运行的状况。
服务器纬度:
作业纬度:可以很明显的看到你各个机器的实例数
数据分片的逻辑很简单,可以参考Elastic Job源码的服务器分片平均算法。以我当前的例子,我库里有一张表的数据为31数据 ,3台服务器(2个实例+1个机器),3个分片,那么 每个服务就对应一个分片,前两个分片分到的数据则都为10, 最后一个分片分的数据应该为11条,应为有未被整除的数据,这块涉及到 除法和求于运算,有忘记的小伙伴们,自己去翻小学的数学课本吧,废话不多话直接上代码和运行结果,如果有更好的建议,欢迎评论。
@Override public void execute(ShardingContext context) { //当前服务器所在的任务分片下标 int shardingItem = context.getShardingItem(); //当任务的分片总数=1时(必须大于0),如果部定时任务工程部署在多个服务器上,则任务将会以1主N从的方式执行。一旦本次执行任务的服务器崩溃,其他执行任务的服务器将会在下次作业启动时选择一个替补执行。如果开启了失效转移,那么功能效果更好,可以保证在本次作业执行时崩溃,备机之一立即启动替补执行 int total=context.getShardingTotalCount(); //查出数量 Map<String,Object> map=new HashMap<>(); List<WxOrderDO> list= payService.getOrderList(map); if(list!=null&&list.size()>0){ //数据库表有多少条记录 int counts=list.size(); //数据总数要大于分片数据,且分片总数大于1时,采用根据分片下标分页查询,否则分片下标为0的获取所有数据,其他分片不获取数据 if(counts>=total&&total>1){ //平均分页多少条数据 int pageSize=new BigDecimal(counts/total).setScale(0).intValue(); //分配不均的情况下 int pageSizeBin=pageSize; //把多出的数据加给最后一个分片 即不能整除的数据(余数)分给最后一个分片 if(counts%total>0 && shardingItem==(total-1)) { pageSizeBin=pageSize+counts%total; } Map<String,Object> pageMap=new HashMap<>(); pageMap.put("start",shardingItem*pageSize); pageMap.put("end",pageSizeBin); payService.getOrderList(pageMap); }else{ //分片下标为0的获取所有数据,其他分片不获取数据 Map<String,Object> pageMap=new HashMap<>(); payService.getOrderList(pageMap); } } }
标红框的是3台服务器:
日志打印效果:
第一台日志:
第二台日志:
第三台日志: