我们知道RocketMQ的NameServer不是强一致性而是最终一致性,即客户端定时获取Broker信息的时间间隔。如果Broker在一段时间内发生故障,客户端无法立即感知到,那么RocketMQ是如何实现消息发送的高可用的呢?大致可以从以下三个方面展开:重试机制顺序替换队列,避免Broker1坏掉,重试机制在发送消息的过程中有这么一段代码:inttimesTotal=communicationMode==CommunicationMode.SYNC?1+这个。defaultMQProducer.getRetryTimesWhenSendFailed():1;整数倍=0;for(;timeselements=this.faultItemTable.elements();ListtmpList=newLinkedList();while(elements.hasMoreElements()){finalFaultItemfaultItem=elements.nextElement();tmpList.add(faultItem);}if(!tmpList.isEmpty()){Collections.shuffle(tmpList);集合排序(tmpList);最终int一半=tmpList。大小()/2;如果(一半<=0){返回tmpList.get(0).getName();}else{finalinti=this.whichItemWorst.getAndIncrement()%half;返回tmpList.get(i).getName();}}返回空值;}开启延迟避免机制。一旦消息发送失败,broker-a就会“悲观地”认为Broker在未来一段时间内不可用。的客户端不会向Broker发送消息。这个延迟时间是由notAvailableDuration和latencyMax共同计算的。首先计算消息发送失败消耗的时间延迟,然后对应latencyMax中的哪个区间,即计算latencyMax的下标,然后返回相同下标对应的notAvailableDuration的延迟值。例如上次请求的延迟超过550Lms,则回退3000Lms;如果超过1000L,则退回60000L;privatelong[]latencyMax={50L,100L,550L,1000L,2000L,3000L,15000L};privatelong[]notAvailableDuration={0L,0L,30000L,60000L,120000L,180000L,600000L};privatelongcomputeNotAvailableDuration(finallongcurrentLatency){for(inti=latencyMax.length-1;i>=0;i--){if(currentLatency>=latencyMax[i])返回this.notAvailableDuration[i];}返回0;您需要谨慎选择是否启用故障避免。一般来说,Broker的忙基本上是瞬时的,很快就能恢复。如果我们启用回避,比如3分钟内不向broker-a发送消息,会导致其他broker上的消息激增,进而导致部分消费者消费消息失败,增加其他消费者的处理压力,以及导致整体消费表现。衰退。因此,在没有特殊场景的情况下,建议不要开启broker的故障规避策略。RocketMQ通过失败重试、顺序替换队列、避免broker故障等方式保证消息发送的高可用。