源码分析ElasticJob故障失效转移机制

本文深入分析了ElasticJob的故障失效转移机制,包括如何判断和执行故障转移,以及故障分片的重新执行逻辑。文章通过源码解读,阐述了在任务节点宕机后,其他节点如何监听并瓜分失效节点的分片,以及如何创建和删除故障转移相关节点,确保任务的顺利执行。此外,还介绍了分片上下文的获取和任务执行流程。

int item = Integer.parseInt(each);

String node = FailoverNode.getExecutionFailoverNode(item);

if (jobNodeStorage.isJobNodeExisted(node) && jobInstanceId.equals(jobNodeStorage.getJobNodeDataDirectly(node))) {

result.add(item);

}

}

Collections.sort(result);

return result;

}

首先获取 n a m e s p a c e / j o b n a m e / s h a r d i n g 目录下的直接子节点 ( 当前的分片信息 ) ,判断 {namespace}/jobname/sharding目录下的直接子节点(当前的分片信息),判断 namespace/jobname/sharding目录下的直接子节点(当前的分片信息),判断{namespace}/jobname/sharding/{item}/failover节点是否存在,如果存在判断该分片是否为当前任务的分片节点,如果是,则返回。该方法的主要目的就是获取已经转移到当前任务节点的分片信息。

代码@5,判断是否有失败分片转移到当前节点,初始状态肯定为空,将执行代码@6,设置故障转移相关准备环境。

代码@6,获取分配给Crashed(宕机的job实例)的所有分片节点,遍历已发生故障的分片,将这些分片设置为故障,待故障转移,设置为故障的实现方法为:创建${namespace}/jobname/leader/failover/items/{item}。

代码@7:执行FailoverService#failoverIfNecessary是否执行故障转移。

/**

  • 如果需要失效转移, 则执行作业失效转移.

*/

public void failoverIfNecessary() {

if (needFailover()) {

jobNodeStorage.executeInLeader(FailoverNode.LATCH, new FailoverLeaderExecutionCallback());

}

}

private boolean needFailover() {

return jobNodeStorage.isJobNodeExisted(FailoverNode.ITEMS_ROOT) && !jobNodeStorage.getJobNodeChildrenKeys(FailoverNode.ITEMS_ROOT).isEmpty()

&& !JobRegistry.getInstance().isJobRunning(jobName);

}

其实现思路:【needFailover方法】首先判断是否存在 n a m e s p a c e / j o b n a m e / l e a d e r / f a i l o v e r / i t e m s 节点是否存在,并且其节点下是否有子节点,并且节点也运行该任务,则需要执行故障失效转移。执行失效转移的逻辑也是进行失效转移选主,其分布式锁节点为: {namespace}/jobname/leader/failover/items节点是否存在,并且其节点下是否有子节点,并且节点也运行该任务,则需要执行故障失效转移。执行失效转移的逻辑也是进行失效转移选主,其分布式锁节点为: namespace/

虽然给定引用未提及 Elastic Job 失效自动转移功能的测试方法,但可以结合 Elastic Job 特性来设计测试方案。 ### 测试环境准备 搭建包含多台服务器的分布式环境,部署 Elastic Job,确保 ZK 注册中心正常运行,配置好作业分片,让多个执行实例正常执行任务。 ### 测试步骤 #### 正常任务执行观察 启动 Elastic Job 作业,使各个执行实例开始执行分配到的任务项。记录每个执行实例对应的作业分片情况,可通过日志或运维平台查看。 #### 模拟服务器下线 在作业执行过程中,选择一台正在执行任务的服务器,模拟其下线(如关闭服务器进程)。观察系统反应,正常情况下,失效转移功能应在短时间内被触发。 #### 验证任务重新分配 查看日志或运维平台,确认下线服务器所分配的作业分片是否被空闲服务器抓取并执行。检查新执行服务器的日志,确保任务能正常继续执行。 #### 检查作业结果一致性 待作业全部执行完毕,检查作业执行结果的一致性。因为失效转移功能可能会影响任务执行顺序,但最终结果应与正常执行情况一致。 #### 多次测试 重复上述步骤多次,模拟不同服务器在不同时间点下线,以验证失效转移功能的稳定性和可靠性。 ### 代码示例(以 Java 为例) ```java import com.dangdang.ddframe.job.api.ShardingContext; import com.dangdang.ddframe.job.api.simple.SimpleJob; import com.dangdang.ddframe.job.config.JobCoreConfiguration; import com.dangdang.ddframe.job.config.simple.SimpleJobConfiguration; import com.dangdang.ddframe.job.lite.api.JobScheduler; import com.dangdang.ddframe.job.lite.config.LiteJobConfiguration; import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperConfiguration; import com.dangdang.ddframe.job.reg.zookeeper.ZookeeperRegistryCenter; public class ElasticJobFailoverTestJob implements SimpleJob { @Override public void execute(ShardingContext shardingContext) { System.out.println("Job sharding item: " + shardingContext.getShardingItem() + " is executing."); } public static void main(String[] args) { // 配置 Zookeeper 注册中心 ZookeeperConfiguration zkConfig = new ZookeeperConfiguration("localhost:2181", "elastic-job-test"); ZookeeperRegistryCenter registryCenter = new ZookeeperRegistryCenter(zkConfig); registryCenter.init(); // 配置作业核心信息 JobCoreConfiguration coreConfig = JobCoreConfiguration.newBuilder("failoverTestJob", "0/5 * * * * ?", 3) .failover(true) // 开启失效转移功能 .build(); // 配置简单作业 SimpleJobConfiguration simpleJobConfig = new SimpleJobConfiguration(coreConfig, ElasticJobFailoverTestJob.class.getCanonicalName()); // 配置 Lite 作业 LiteJobConfiguration liteJobConfig = LiteJobConfiguration.newBuilder(simpleJobConfig).build(); // 启动作业调度器 new JobScheduler(registryCenter, liteJobConfig).init(); } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值