xxljob failover故障转移失效

背景

​ 实施团队发现某些业务数据不正确,经查,定时任务尚未执行。双节点微服务中 ,主节点出现过“假死”,但xxljob明明配置了failover,为什么备节点不执行?是failover机制有BUG还是其他原因导致?

分析过程

首先,确认下配置是否正确,经查如下,确实是faillover模式,不存在问题。

在这里插入图片描述

其次,梳理failover执行逻辑

在JobTrigger主逻辑中是“先选择地址,再执行任务”,去找地址选举是由ExecutorRouteFailover完成

在这里插入图片描述

看看ExecutorRouteFailover地址是怎么选取的:从头到尾遍历地址列表,每个地址执行心跳检测,心跳成功,则返回该地址;若失败,进行下一个地址检测。

​ 循环心跳如图:

在这里插入图片描述

​ 心跳具体检测逻辑值简单发送http空请求,请求地址为addressUrl + “beat”

在这里插入图片描述

第三:分析xxljob日志,为了便于描述,微服务主节点为22节点,备节点为21节点

​ 任务没有执行,有可能是调度器本身问题,有可能是执行器问题,通过查询同一时间节点的其他任务,如图,以“第一个”为执行策略的的任务触发正确,排除调度器本身问题。

在这里插入图片描述

​ 再看下该任务的所有状态(成功、失败)发现那个时间段failover有成功的。找了两笔,"心跳阶段"和22节点交互时有错:读超时和连接拒绝。

在这里插入图片描述
在这里插入图片描述

​ 既然faillover没有错,那是什么问题导致呢?接着查14:55的日志,发现几笔都是“标记失败”,关键是“执行时间”为17:05分,差了好几个小时。如下图:
在这里插入图片描述

第四、分析“标记失败”

​ 搜索代码后发现,JobCompleteHelper是唯一写入”标记失败的“类,他循环遍历吧超过10分钟的未上报的请求,记录为”标记失败“,如下

在这里插入图片描述

​ 对应SQL逻辑是查找已经提交的,还在“处理中”(执行器接收、处理结果返回是异步的,是两个阶段的,为了可靠性这样设计),并且”执行地址不存在xxl_job_registry表中“如下

在这里插入图片描述

​ 理解"执行地址不存在"是关键,因为xxl_job_registry数据由执行器(微服务节点)上传(由admin的JobApiController接收),超过90秒后定时任务会自动删除(这样设计的主要原因是避免在一个“有问题”的节点上调用),xxl_job_registry DAO如下

在这里插入图片描述

现场还原

​ 下午14:50由于22节点出问题了,不只本任务failover有问题 、其他任务调用也失败,说明22节点是真出问题了。但这个是过程是渐渐的:刚开始failover心跳没问题、后来出现连接不上或读超时问题、再后来业务出现问题导致无法回调执行结果,也就是执行结果是“处理中”,最后业务节点也无法上报自己的配置心跳信息(xxl_job_registry),这就是为什么任务调度时间从14:50多开始到执行结束时间17:05分之间(执行结束是由JobCompleteHelper找从调度开始超过10分钟的还在处理中的,并且服务不上报心跳了)有这么长的时差。

如何优化

​ 回过头来捋一捋failover逻辑:先心跳一个地址,确认无误后就直接执行了。这里面的问题在于没有考虑执行器节点历史执行情况,因为执行器接收心跳后,没有执行业务逻辑就返回了,如果业务有问题或节点假死,有可能心态还能返回,但是业务等其他操作无法继续,如果选择这个地址,那业务任然无法执行。因此逻辑应改为如下:

​ 依然心跳每个地址,以排除网络都无法处理的情况,最终会产生一个候选列表;

能返回,但是业务等其他操作无法继续,如果选择这个地址,那业务任然无法执行。因此逻辑应改为如下:

​ 依然心跳每个地址,以排除网络都无法处理的情况,最终会产生一个候选列表;

​ 如果候选列表中有多个地址,则选择“标记时间”最远或不存在的节点。

  • 23
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值