最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RocketMQ生產(chǎn)者如何規(guī)避故障Broker方式詳解

 更新時(shí)間:2022年11月29日 10:21:48   作者:夢(mèng)想實(shí)現(xiàn)家_Z  
這篇文章主要為大家介紹了RocketMQ生產(chǎn)者如何規(guī)避故障Broker方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

在消息發(fā)送過程中,生產(chǎn)者從NameServer中獲取到了指定Topic對(duì)應(yīng)的Broker信息,在同步發(fā)送消息的代碼中,如果消息發(fā)送失敗,生產(chǎn)者默認(rèn)是會(huì)重試兩次的。那么Broker有問題的情況下,無論重試多少次都是沒有意義的,消息生產(chǎn)者是如何規(guī)避這些故障Broker的呢?

收集故障Broker

我們?cè)谒械陌l(fā)送消息源碼中都可以找到這樣一段代碼,可在DefaultMQProducerImpl類中查找:

this.updateFaultItem(mq.getBrokerName(), endTimestamp - beginTimestampPrev, true);

無論是發(fā)送成功還是失敗,RocketMQ生產(chǎn)者客戶端都會(huì)做這一步操作:

// 發(fā)送成功的話,isolation傳false,失敗isolation傳true
public void updateFaultItem(final String brokerName, final long currentLatency, boolean isolation) {
    if (this.sendLatencyFaultEnable) {
        long duration = computeNotAvailableDuration(isolation ? 30000 : currentLatency);
        this.latencyFaultTolerance.updateFaultItem(brokerName, currentLatency, duration);
    }
}
private long computeNotAvailableDuration(final long currentLatency) {
    for (int i = latencyMax.length - 1; i >= 0; i--) {
        if (currentLatency >= latencyMax[i])
            return this.notAvailableDuration[i];
    }
    return 0;
}
private long[] notAvailableDuration = {0L, 0L, 30000L, 60000L, 120000L, 180000L, 600000L};

如果Broker產(chǎn)生故障,那么會(huì)創(chuàng)建一個(gè)FaultItem對(duì)象記錄故障的Broker,并把結(jié)果放進(jìn)故障規(guī)避表faultItemTable中,數(shù)據(jù)格式如下:

"broker-a": {
  // broker名稱
  "name": "broker-a",
  "currentLatency": 發(fā)送消息消耗的時(shí)間,毫秒值之差,
  // 解除規(guī)避的時(shí)間,絕對(duì)時(shí)間
  "startTimestamp": 時(shí)間戳毫秒值
},
"broker-b": {
  // broker名稱
  "name": "broker-b",
  "currentLatency": 發(fā)送消息消耗的時(shí)間,毫秒值之差,
  // 解除規(guī)避的時(shí)間,絕對(duì)時(shí)間
  "startTimestamp": 時(shí)間戳毫秒值
}

發(fā)送成功的Broker設(shè)置的故障規(guī)避時(shí)間為0,發(fā)送失敗的Broker將被設(shè)置為規(guī)避30秒;

選擇Broker

MQFaultStrategy.selectOneMessageQueue()方法中,我們分三部分來分析如何選擇Broker。

  • 輪詢選擇一個(gè)可用的Broker
// 輪詢的基本套路,一個(gè)自增變量
int index = tpInfo.getSendWhichQueue().incrementAndGet();
for (int i = 0; i < tpInfo.getMessageQueueList().size(); i++) {
     // 通過對(duì)隊(duì)列數(shù)量取模,獲取選定的Broker所在的位置
     int pos = Math.abs(index++) % tpInfo.getMessageQueueList().size();
     if (pos < 0)
         pos = 0;
     MessageQueue mq = tpInfo.getMessageQueueList().get(pos);
     // 判斷Broker是否在規(guī)避時(shí)間內(nèi),如果不在規(guī)避時(shí)間內(nèi),就選擇這個(gè)Broker,否則繼續(xù)循環(huán)直至所有Broker都在規(guī)避時(shí)間內(nèi)
     if (latencyFaultTolerance.isAvailable(mq.getBrokerName()))
         return mq;
}

1.輪詢的基本套路都是通過一個(gè)自增變量來對(duì)所有的Broker數(shù)量取模,這樣就可以命中一個(gè)Broker;

2.針對(duì)命中的Broker判斷是否在規(guī)避時(shí)間范圍內(nèi),不在規(guī)避時(shí)間內(nèi)就可以返回;否則只能進(jìn)入第二個(gè)方案;

  • 選擇一個(gè)相對(duì)延遲低的Broker
// 把所有規(guī)避列表中的Broker按延遲高低排序,并從延遲低的Broker中選擇一個(gè)
final String notBestBroker = latencyFaultTolerance.pickOneAtLeast();
int writeQueueNums = tpInfo.getQueueIdByBroker(notBestBroker);
// 判斷該Broker是否允許寫消息
if (writeQueueNums > 0) {
    final MessageQueue mq = tpInfo.selectOneMessageQueue();
    if (notBestBroker != null) {
        mq.setBrokerName(notBestBroker);
        mq.setQueueId(tpInfo.getSendWhichQueue().incrementAndGet() % writeQueueNums);
    }
    // 返回選中的Broker
    return mq;
}

1.從規(guī)避列表中找到延時(shí)比較低的Broker;

2.判斷該Broker是否允許寫消息,允許寫消息的話就直接返回,否則再進(jìn)入下一個(gè)方案;

  • 默認(rèn)的選擇
return tpInfo.selectOneMessageQueue();

最后直接輪詢一個(gè)Broker直接返回:

    public MessageQueue selectOneMessageQueue() {
        int index = this.sendWhichQueue.incrementAndGet();
        int pos = Math.abs(index) % this.messageQueueList.size();
        if (pos < 0)
            pos = 0;
        return this.messageQueueList.get(pos);
    }

該方案是默認(rèn)方案,沒有開啟故障規(guī)避配置的話,所有Broker的選擇都是使用的該方案;

小結(jié)

RocketMQ通過設(shè)置故障規(guī)避表的方式,把所有的Broker的延遲數(shù)據(jù)都保留在故障規(guī)避表中,根據(jù)該列表制定了以下幾種策略:

1.優(yōu)先選擇不在規(guī)避時(shí)間范圍內(nèi)的Broker

2.如果所有Broker都在規(guī)避時(shí)間內(nèi),優(yōu)先選擇延遲低的Broker;

3.如果依然沒有選中合適的Broker,那么就直接挑一個(gè)Broker來用;

以上就是RocketMQ生產(chǎn)者如何規(guī)避故障Broker方式詳解的詳細(xì)內(nèi)容,更多關(guān)于RocketMQ生產(chǎn)者規(guī)避故障Broker的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot2.x 集成 Thymeleaf的詳細(xì)教程

    SpringBoot2.x 集成 Thymeleaf的詳細(xì)教程

    本文主要對(duì)SpringBoot2.x集成Thymeleaf及其常用語法進(jìn)行簡(jiǎn)單總結(jié),其中SpringBoot使用的2.4.5版本。對(duì)SpringBoot2.x 集成 Thymeleaf知識(shí)感興趣的朋友跟隨小編一起看看吧
    2021-07-07
  • 詳解Spring與Mybatis整合方法(基于IDEA中的Maven整合)

    詳解Spring與Mybatis整合方法(基于IDEA中的Maven整合)

    這篇文章主要介紹了Spring與Mybatis整合方法(基于IDEA中的Maven整合),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java 基礎(chǔ)--Arrays工具類詳解

    Java 基礎(chǔ)--Arrays工具類詳解

    這篇文章主要介紹了Java Arrays工具類用法,結(jié)合實(shí)例形式分析了java Arrays工具類針對(duì)數(shù)組元素修改、復(fù)制、排序等操作使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2021-09-09
  • Java Condition類案例詳解

    Java Condition類案例詳解

    這篇文章主要介紹了Java Condition類案例詳解,本篇文章通過簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-09-09
  • 深入探究Java?@MapperScan實(shí)現(xiàn)原理

    深入探究Java?@MapperScan實(shí)現(xiàn)原理

    之前是直接在Mapper類上面添加注解@Mapper,這種方式要求每一個(gè)mapper類都需要添加此注解,麻煩。通過使用@MapperScan可以指定要掃描的Mapper類的包的路徑,這篇文章深入探究Java?@MapperScan的實(shí)現(xiàn)原理
    2023-01-01
  • mybatis-generator如何自定義注釋生成

    mybatis-generator如何自定義注釋生成

    這篇文章主要介紹了mybatis-generator如何自定義注釋生成的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java 基礎(chǔ)語法讓你弄懂類和對(duì)象

    Java 基礎(chǔ)語法讓你弄懂類和對(duì)象

    C 語言是面向過程的,而 Java 是面向?qū)ο笫俏覀兂B牭降囊痪湓挘@章將帶你揭曉Java 基礎(chǔ)語法中類與對(duì)象到底是什么,需要的朋友請(qǐng)參考下文
    2021-08-08
  • 詳解Spring Boot配置使用Logback進(jìn)行日志記錄的實(shí)戰(zhàn)

    詳解Spring Boot配置使用Logback進(jìn)行日志記錄的實(shí)戰(zhàn)

    本篇文章主要介紹了詳解Spring Boot配置使用Logback進(jìn)行日志記錄的實(shí)戰(zhàn),具有一定的參考價(jià)值,有興趣的朋友可以了解一下
    2017-07-07
  • springMVC幾種頁(yè)面跳轉(zhuǎn)方式小結(jié)

    springMVC幾種頁(yè)面跳轉(zhuǎn)方式小結(jié)

    本篇文章主要介紹了springMVC 幾種頁(yè)面跳轉(zhuǎn)方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-02-02
  • Java中import java.util.Scanner的用處詳解

    Java中import java.util.Scanner的用處詳解

    文章主要介紹Java中的Scanner類及其常用方法next()和nextLine()的區(qū)別,next()方法在遇到空格、Tab鍵、回車鍵等分隔符時(shí)結(jié)束輸入,而nextLine()方法則接收所有輸入,直到遇到回車鍵
    2024-11-11

最新評(píng)論

会同县| 贵南县| 曲松县| 玉环县| 神木县| 兴安盟| 榆林市| 岗巴县| 翁牛特旗| 宜章县| 越西县| 阿合奇县| 武功县| 新民市| 如皋市| 临沭县| 唐河县| 贡觉县| 芒康县| 彭泽县| 桑植县| 罗定市| 信阳市| 沙湾县| 那曲县| 民乐县| 涞水县| 吉木萨尔县| 榆中县| 新沂市| 青浦区| 陕西省| 五家渠市| 华蓥市| 郧西县| 桐乡市| 长垣县| 郑州市| 昌平区| 浮梁县| 沙雅县|