wjdxw commented on issue #2429:
URL: 
https://github.com/apache/shardingsphere-elasticjob/issues/2429#issuecomment-2288825840

   
   找到真实原因了
   **A节点宕机  B 节点监听 相关失效转移节点操作**
   
   
   1.找到服务器A   sharding/{分片}/running
   public void setCrashedFailoverFlag(final int item) {
           if (!isFailoverAssigned(item)) {
               
jobNodeStorage.createJobNodeIfNeeded(FailoverNode.getItemsNode(item));
               
jobNodeStorage.removeJobNodeIfExisted(ShardingNode.getRunningNode(item));
           }
   }
   sharing/{分片}/failover 节点不存在,创建/leader/failover/items//{分片}/  删除  
sharding//{分片}/running
   
   failoverIfNecessary()
   /leader/failover/items 节点存在 && /leader/failover/items 当前节点需要有子节点
   当前实例的job 不在运行状态
   /leader/failover/latch 节点选主成功后,执行FailoverLeaderExecutionCallback回调操作
   needFailover()
   
   创建 sharding/{分片}/failover
   创建 sharding/{分片}/failovering
   删除 leader/failover/items/{分片}
   执行execute()
   
   
   此时B节点正在执行当前分片的实效转移,执行过程中
   创建sharding/{分片}/running 
   
   服务器A 重启成功 
   由于job执行时间较长
   此时服务器B重启,服务器B宕机,使用kill-9 后面的都不会执行
   ### 
   
   (_等待执行完成之后
   删除 sharding/{分片}/failover
   删除 sharding/{分片}/failovering
   删除 创建sharding/{分片}/running_ )不执行
   
   
   **B节点宕机,A节点监听**
   1.拿到sharding/{分片}/failovering 
   相关的信息进行失效转移 
   public void setCrashedFailoverFlagDirectly(final int item) {
           
jobNodeStorage.createJobNodeIfNeeded(FailoverNode.getItemsNode(item));
       }
   这边的逻辑不会去删除running 节点,对于异常宕机的服务器,可能就会导致一些节点无法删除
   执行execute()
   
   
   此时正常A节点和B节点 都应该继续执行job,但是却没有执行
   
   因为sharding/{分片}/running 这个节点一直存在,在执行代码的时候会执行这一段代码 
waitingOtherShardingItemCompleted();
   private void waitingOtherShardingItemCompleted() {
           while (executionService.hasRunningItems()) {
               log.debug("Job '{}' sleep short time until other job 
completed.", jobName);
               BlockUtils.waitingShortTime();
           }
       }
   
   这边会判断是否有running 
的节点,实际上这边有running的节点一直没有消失,所以代码一直会阻塞在这里,导致无法进行执行,如果是此异常,可以通过删除sharding/{分片}/running,这样就可以继续执行了,执行之后也会正常
   删除 sharding/{分片}/failover
   删除 sharding/{分片}/failovering
   
   
   
   
   Job正常还有启动的时候的监听,继续如上B节点宕机,B节点也会启动,B节点启动之后做了什么操作
   **B节点启动,A节点监听**
   
   如果只有一个实例时
   获取 sharding/{分片}/failovering 
,如果执行当前failering的实例不可以用,删除sharding/{分片}/failovering
   获取 sharing/分片/running,如果执行当前的running的实例不可用,删除删除sharding/{分片}/failovering
   
   
源码在的判断是否只有一个实例的时候,由于生产的实例A节点在,B节点启动的时候就试两个,代码永远走不到下面,所以这个runinng的节点一直存在,就导致一直无法执行
   
   所以源码这个判断逻辑有三个优化点:
   1. 在执行waitingOtherShardingItemCompleted 方法的时候,hasRunningItems 这边也应该判断下 
running 的节点是否是在可用的节点上,不然无效的节点running 也会造成阻塞
   2.setCrashedFailoverFlagDirectly 的时候,如果一些异常宕机,造成runnning 
和failovering节点在的时候,这边就不会清理runinng 节点
   3.isTheOnlyInstance 这个方法是否可以去掉,对于生产,不会只有一个实例存在的情况,除非第一次第一个实例上生产。
   
   
   
   
   
   
   
   
   
   
   
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to