分布式调度平台Elastic-Job失效转移功能的bug

试了各种办法模拟失效转移都不成功,仔细研究了源码,发现源码中有两个小bug。

class JobCrashedJobListener extends AbstractJobListener {

    @Override
    protected void dataChanged(final String path, final Type eventType, final String data) {
        if (isFailoverEnabled() && Type.NODE_REMOVED == eventType && instanceNode.isInstancePath(path)) {
            String jobInstanceId = path.substring(instanceNode.getInstanceFullPath().length() + 1);
            if (jobInstanceId.equals(JobRegistry.getInstance().getJobInstance(jobName).getJobInstanceId())) {
                return;
            }
            List<Integer> failoverItems = failoverService.getFailoverItems(jobInstanceId);
            if (!failoverItems.isEmpty()) {
                for (int each : failoverItems) {
                    failoverService.setCrashedFailoverFlag(each);
                    failoverService.failoverIfNecessary();
                }
            } else {
                for (int each : shardingService.getShardingItems(jobInstanceId)) {
                    failoverService.setCrashedFailoverFlag(each);
                    failoverService.failoverIfNecessary();
                }
            }
        }
    }
}

失效转移是从这个监听器开始的,当zookeeper上有服务器节点被Removed时,触发监听,查询该服务器被分配的任务项

/**
     * 获取作业运行实例的分片项集合.
     *
     * @param jobInstanceId 作业运行实例主键
     * @return 作业运行实例的分片项集合
     */
    public List<Integer> getShardingItems(final String jobInstanceId) {
        JobInstance jobInstance = new JobInstance(jobInstanceId);
        if (!serverService.isAvailableServer(jobInstance.getIp())) {
            return Collections.emptyList();
        }
        List<Integer> result = new LinkedList<>();
        int shardingTotalCount = configService.load(true).getTypeConfig().getCoreConfig().getShardingTotalCount();
        for (int i = 0; i < shardingTotalCount; i++) {
            if (jobInstance.getJobInstanceId().equals(jobNodeStorage.getJobNodeData(ShardingNode.getInstanceNode(i)))) {
                result.add(i);
            }
        }
        return result;
    }

在查询宕机服务器分配的任务项时,先判断该服务器是否可用,如果可用,才继续查询

public boolean isAvailableServer(final String ip) {
return isEnableServer(ip) && hasOnlineInstances(ip);
}

private boolean hasOnlineInstances(final String ip) {
    for (String each : jobNodeStorage.getJobNodeChildrenKeys(InstanceNode.ROOT)) {
        if (each.startsWith(ip)) {
            return true;
        }
    }
    return false;
}

判断服务器节点是否可用的方法如上,如果服务器节点存在,认为可用,这与上面失效转移监听被触发的条件(服务器节点被removed)相矛盾。

失效转移功能另外一个bug就是在JobCrashedJobListener监听器中还应该加个判断

if(!JobRegistry.getInstance().isJobRunning(jobName)){
return;
}
开启表示如果作业在一次任务执行中途宕机,允许将该次未完成的任务在另一作业节点上补偿执行
这句话是文档上说的,所有我认为应该加上这个判断

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值