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

Alibaba?Nacos配置中心動態(tài)感知原理示例解析

 更新時間:2023年08月02日 08:44:25   作者:Mr.Fire  
這篇文章主要介紹了Alibaba?Nacos配置中心動態(tài)感知原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

Nacos提供兩大核心功能,服務(wù)注冊發(fā)現(xiàn),配置中心。對應(yīng)Nacos的架構(gòu)圖,分別是Naming Service和Config Service,其中Config Service是實現(xiàn)配置中心的核心模塊。實現(xiàn)了版本管理、灰度發(fā)布、監(jiān)聽管理、推送軌跡等功能。針對配置中心,當我們通過控制臺或API修改配置之后,客戶端能動態(tài)獲取到修改后的配置,那么配置中心是如何實現(xiàn)動態(tài)感知的呢?

動態(tài)監(jiān)聽之Pull和Push

當Nacos Config Server上的配置發(fā)生變化時,需要讓相關(guān)的應(yīng)用程序感知到配置的變化,這就需要客戶端對感興趣的配置實現(xiàn)監(jiān)聽。那么客戶端是如何實現(xiàn)配置變更實時更新的呢?

一般來說,客戶端與服務(wù)端的交互無非兩種:Pull模式和Push模式,一個是客戶端主動拉取,一個是服務(wù)端主動推送。

  • Pull模式:服務(wù)端和客戶端之間需要維護長連接,客戶端多的情況下耗內(nèi)存、需要心跳機制檢測連接狀態(tài)。
  • Push模式:客戶端需要定時拉取數(shù)據(jù),不能保證實時性,服務(wù)端長時間不更新的情況下,定時任務(wù)為無效更新,浪費資源。

Nacos的Pull模式

Nacos采用的是Pull模式,不過不是簡單的Pull,而是一種長輪詢機制。結(jié)合Pull和Push兩者的優(yōu)勢,客戶端采用長輪詢的方式發(fā)起Pull請求,檢查服務(wù)配置消息是否發(fā)生變化,如果更新,客戶端會根據(jù)變更的內(nèi)容獲取最新配置信息。

所謂的長輪詢,就是客戶端發(fā)起Pull請求之后,服務(wù)端如果發(fā)生配置變更則立即返回,如果服務(wù)端和客戶端配置是保持一致的,那么服務(wù)端會“Hold”住這個請求,在指定時間內(nèi)不返回結(jié)果,直到這段時間內(nèi)配置發(fā)生變化。這個長連接默認超時時間是30s。

服務(wù)端收到請求后,先檢查配置是否發(fā)生變化,如果沒變化,則設(shè)置一個定時任務(wù),延期29.5s執(zhí)行,并且把當前的客戶端長輪詢連接加入allSubs隊列。這里有兩種方式觸發(fā)連接返回。

  • 等待29.5s自動觸發(fā)檢查機制,無論是否發(fā)生變化,都會返回。
  • 在29.5s內(nèi),通過Nacos控制臺或者API的形式對配置進行了修改,會觸發(fā)ConfigDataChangeEvent事件。

Nacos的動態(tài)感知

前面我們已經(jīng)知道客戶端通過長輪詢請求來獲取配置變更,但是定時任務(wù)是延遲執(zhí)行的,那并沒有達到實時的目的,當通過控制臺或者API修改配置時,那Nacos是如何實時動態(tài)更新的呢?

LongPollingService 監(jiān)聽事件類

LongPollingService繼承AbstractEventListener,AbstractEventListener是事件抽象類,它有一個onEvent抽象方法,而LongPollingService實現(xiàn)了這個方法

@Override
public void onEvent(Event event) {
    if (isFixedPolling()) {
        // ignore
    } else {
        if (event instanceof LocalDataChangeEvent) {
            LocalDataChangeEvent evt = (LocalDataChangeEvent)event;
            scheduler.execute(new DataChangeTask(evt.groupKey, evt.isBeta, evt.betaIps));
        }
    }
}

LongPollingService可以看到LocalDataChangeEvent事件,這個事件是服務(wù)端的配置數(shù)據(jù)發(fā)生變化時發(fā)布的一個事件。onEvent方法中通過線程池來執(zhí)行一個DataChangeTask任務(wù)。

DataChangeTask線程

DataChangeTask是一個線程,實現(xiàn)了Runnable接口,對應(yīng)的run()如下:

class DataChangeTask implements Runnable {
    @Override
    public void run() {
        try {
            ConfigService.getContentBetaMd5(groupKey);
            for (Iterator<ClientLongPolling> iter = allSubs.iterator(); iter.hasNext(); ) {
                ClientLongPolling clientSub = iter.next();
                if (clientSub.clientMd5Map.containsKey(groupKey)) {
                    // 如果beta發(fā)布且不在beta列表直接跳過
                    if (isBeta && !betaIps.contains(clientSub.ip)) {
                        continue;
                    }
                    // 如果tag發(fā)布且不在tag列表直接跳過
                    if (StringUtils.isNotBlank(tag) && !tag.equals(clientSub.tag)) {
                        continue;
                    }
                    getRetainIps().put(clientSub.ip, System.currentTimeMillis());
                    iter.remove(); // 刪除訂閱關(guān)系
                    LogUtil.clientLog.info("{}|{}|{}|{}|{}|{}|{}",
                        (System.currentTimeMillis() - changeTime),
                        "in-advance",
                        RequestUtil.getRemoteIp((HttpServletRequest)clientSub.asyncContext.getRequest()),
                        "polling",
                        clientSub.clientMd5Map.size(), clientSub.probeRequestSize, groupKey);
                    clientSub.sendResponse(Arrays.asList(groupKey));
                }
            }
        } catch (Throwable t) {
            LogUtil.defaultLog.error("data change error:" + t.getMessage(), t.getCause());
        }
    }
    DataChangeTask(String groupKey) {
        this(groupKey, false, null);
    }
    DataChangeTask(String groupKey, boolean isBeta, List<String> betaIps) {
        this(groupKey, isBeta, betaIps, null);
    }
    DataChangeTask(String groupKey, boolean isBeta, List<String> betaIps, String tag) {
        this.groupKey = groupKey;
        this.isBeta = isBeta;
        this.betaIps = betaIps;
        this.tag = tag;
    }
    final String groupKey;
    final long changeTime = System.currentTimeMillis();
    final boolean isBeta;
    final List<String> betaIps;
    final String tag;
}
  • 遍歷allSubs中的客戶端長輪詢請求。
  • 比較每個客戶端長輪詢請求攜帶的groupKey,如果服務(wù)端變更的配置和客戶端請求關(guān)注的配置一致,則直接返回,這里調(diào)用clientSub.sendResponse()方法返回。

總結(jié)

好了,最后整理下nacos實時動態(tài)感知的流程如下:

  • 客戶端通過長輪詢的方式發(fā)起Pull請求服務(wù)端獲取配置變更;
  • 服務(wù)端判斷如果是長輪詢請求,對比數(shù)據(jù)的MD5,如果發(fā)生變化則直接返回,否則通過延遲任務(wù)執(zhí)行ClientLongPolling線程;
  • 配置中心修改配置后,會發(fā)布ConfigDataChangeEvent事件;
  • EventDispatcher觸發(fā)事件,通知監(jiān)聽者。LongPollingService就是監(jiān)聽者之一。
  • 監(jiān)聽者通過線程池開啟定時線程,遍歷客戶端的所有長輪詢的請求, 通過groupKey匹配到對應(yīng)請求,直接返回。

以上就是Alibaba Nacos配置中心動態(tài)感知原理示例解析的詳細內(nèi)容,更多關(guān)于Alibaba Nacos配置中心動態(tài)感知的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序?qū)崿F(xiàn)代碼

    java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序?qū)崿F(xiàn)代碼

    這篇文章主要介紹了java 數(shù)據(jù)結(jié)構(gòu) 冒泡排序的相關(guān)資料,并附實例代碼,有需要的小伙伴可以參考下
    2016-09-09
  • Java圖片處理之獲取gif圖一幀圖片的兩種方法

    Java圖片處理之獲取gif圖一幀圖片的兩種方法

    這篇文章主要給大家介紹了關(guān)于Java圖片處理之獲取gif圖一幀圖片的兩種方法,分別是利用Java原生代碼和使用im4java調(diào)用ImageMagick來實現(xiàn),兩種方法都給出來示例代碼供大家參考學習,需要的朋友們下面來一起看看吧。
    2017-10-10
  • 在SpringBoot中整合數(shù)據(jù)源的示例詳解

    在SpringBoot中整合數(shù)據(jù)源的示例詳解

    這篇文章主要介紹了在SpringBoot中如何整合數(shù)據(jù)源,本文介紹了如何在SpringBoot項目中整合常見的數(shù)據(jù)源,包括JdbcTemplate、MyBatis和JPA,并探討了如何配置和使用多數(shù)據(jù)源,需要的朋友可以參考下
    2023-06-06
  • Java中的JScrollPane使用詳細說明

    Java中的JScrollPane使用詳細說明

    這篇文章主要給大家介紹了關(guān)于Java中JScrollPane使用的相關(guān)資料,Java JScrollPane是Swing庫提供的一個組件,用于在需要滾動的區(qū)域中顯示內(nèi)容,需要的朋友可以參考下
    2024-07-07
  • Java Class.forName()用法和newInstance()方法原理解析

    Java Class.forName()用法和newInstance()方法原理解析

    這篇文章主要介紹了Java Class.forName()用法和newInstance()方法原理解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • Jenkins初級應(yīng)用之Invoke?Phing?targets插件配置

    Jenkins初級應(yīng)用之Invoke?Phing?targets插件配置

    這篇文章主要為大家介紹了Jenkins初級應(yīng)用之Invoke?Phing?targets的插件配置,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪<BR>
    2022-04-04
  • Java使用PDFBox實現(xiàn)調(diào)整PDF每頁格式

    Java使用PDFBox實現(xiàn)調(diào)整PDF每頁格式

    這篇文章主要為大家詳細介紹了Java如何使用PDFBox實現(xiàn)調(diào)整PDF每頁格式,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
    2024-03-03
  • Maven項目中resources配置總結(jié)

    Maven項目中resources配置總結(jié)

    這篇文章主要介紹了Maven項目中resources配置總結(jié),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-03-03
  • 舉例詳解用Java實現(xiàn)web分頁功能的方法

    舉例詳解用Java實現(xiàn)web分頁功能的方法

    這篇文章主要介紹了舉例詳解用Java實現(xiàn)web分頁功能的方法,這種基本功能現(xiàn)一般通過Hibernate框架來完成,需要的朋友可以參考下
    2015-10-10
  • Java 數(shù)組聲明、創(chuàng)建、初始化詳解

    Java 數(shù)組聲明、創(chuàng)建、初始化詳解

    本文主要介紹Java 數(shù)組聲明、創(chuàng)建、初始化的資料,這里整理相關(guān)知識,及簡單實現(xiàn)代碼,幫助大家學習,有興趣的小伙伴可以參考下
    2016-09-09

最新評論

甘谷县| 历史| 巫山县| 江西省| 汽车| 光山县| 岐山县| 水富县| 新田县| 宜兰县| 历史| 德庆县| 隆尧县| 老河口市| 彩票| 洛南县| 洪泽县| 汶上县| 泰顺县| 桐城市| 偏关县| 甘泉县| 江西省| 游戏| 柳河县| 兰坪| 奎屯市| 尉犁县| 沾化县| 德令哈市| 新干县| 乐亭县| 花垣县| 井陉县| 沂南县| 建始县| 祥云县| 秦皇岛市| 伊吾县| 安多县| 临武县|