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

阿里面試Nacos配置中心交互模型是push還是pull原理解析

 更新時(shí)間:2022年07月23日 11:19:57   作者:程序員小富  
這篇文章主要為大家介紹了阿里面試Nacos配置中心交互模型是push還是pull原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

對(duì)于Nacos大家應(yīng)該都不太陌生,出身阿里名聲在外,能做動(dòng)態(tài)服務(wù)發(fā)現(xiàn)、配置管理,非常好用的一個(gè)工具。然而這樣的技術(shù)用的人越多面試被問(wèn)的概率也就越大,如果只停留在使用層面,那面試可能要吃大虧。

比如我們今天要討論的話題,Nacos在做配置中心的時(shí)候,配置數(shù)據(jù)的交互模式是服務(wù)端推過(guò)來(lái)還是客戶端主動(dòng)拉的?

這里我先拋出答案:客戶端主動(dòng)拉的!

接下來(lái)咱們扒一扒Nacos的源碼,來(lái)看看它具體是如何實(shí)現(xiàn)的?

配置中心

Nacos之前簡(jiǎn)單回顧下配置中心的由來(lái)。

簡(jiǎn)單理解配置中心的作用就是對(duì)配置統(tǒng)一管理,修改配置后應(yīng)用可以動(dòng)態(tài)感知,而無(wú)需重啟。

因?yàn)樵趥鹘y(tǒng)項(xiàng)目中,大多都采用靜態(tài)配置的方式,也就是把配置信息都寫在應(yīng)用內(nèi)的ymlproperties這類文件中,如果要想修改某個(gè)配置,通常要重啟應(yīng)用才可以生效。

但有些場(chǎng)景下,比如我們想要在應(yīng)用運(yùn)行時(shí),通過(guò)修改某個(gè)配置項(xiàng),實(shí)時(shí)的控制某一個(gè)功能的開(kāi)閉,頻繁的重啟應(yīng)用肯定是不能接受的。

尤其是在微服務(wù)架構(gòu)下,我們的應(yīng)用服務(wù)拆分的粒度很細(xì),少則幾十多則上百個(gè)服務(wù),每個(gè)服務(wù)都會(huì)有一些自己特有或通用的配置。假如此時(shí)要改變通用配置,難道要我挨個(gè)改幾百個(gè)服務(wù)配置?很顯然這不可能。所以為了解決此類問(wèn)題配置中心應(yīng)運(yùn)而生。

配置中心

推與拉模型

客戶端與配置中心的數(shù)據(jù)交互方式其實(shí)無(wú)非就兩種,要么推push,要么拉pull。

推模型

客戶端與服務(wù)端建立TCP長(zhǎng)連接,當(dāng)服務(wù)端配置數(shù)據(jù)有變動(dòng),立刻通過(guò)建立的長(zhǎng)連接將數(shù)據(jù)推送給客戶端。

優(yōu)勢(shì):長(zhǎng)鏈接的優(yōu)點(diǎn)是實(shí)時(shí)性,一旦數(shù)據(jù)變動(dòng),立即推送變更數(shù)據(jù)給客戶端,而且對(duì)于客戶端而言,這種方式更為簡(jiǎn)單,只建立連接接收數(shù)據(jù),并不需要關(guān)心是否有數(shù)據(jù)變更這類邏輯的處理。

弊端:長(zhǎng)連接可能會(huì)因?yàn)榫W(wǎng)絡(luò)問(wèn)題,導(dǎo)致不可用,也就是俗稱的假死。連接狀態(tài)正常,但實(shí)際上已無(wú)法通信,所以要有的心跳機(jī)制KeepAlive來(lái)保證連接的可用性,才可以保證配置數(shù)據(jù)的成功推送。

拉模型

客戶端主動(dòng)的向服務(wù)端發(fā)請(qǐng)求拉配置數(shù)據(jù),常見(jiàn)的方式就是輪詢,比如每3s向服務(wù)端請(qǐng)求一次配置數(shù)據(jù)。

輪詢的優(yōu)點(diǎn)是實(shí)現(xiàn)比較簡(jiǎn)單。但弊端也顯而易見(jiàn),輪詢無(wú)法保證數(shù)據(jù)的實(shí)時(shí)性,什么時(shí)候請(qǐng)求?間隔多長(zhǎng)時(shí)間請(qǐng)求一次?都是不得不考慮的問(wèn)題,而且輪詢方式對(duì)服務(wù)端還會(huì)產(chǎn)生不小的壓力。

長(zhǎng)輪詢

開(kāi)篇我們就給出了答案,nacos采用的是客戶端主動(dòng)拉pull模型,應(yīng)用長(zhǎng)輪詢(Long Polling)的方式來(lái)獲取配置數(shù)據(jù)。

額?以前只聽(tīng)過(guò)輪詢,長(zhǎng)輪詢又是什么鬼?它和傳統(tǒng)意義上的輪詢(暫且叫短輪詢吧,方便比較)有什么不同呢?

短輪詢

不管服務(wù)端配置數(shù)據(jù)是否有變化,不停的發(fā)起請(qǐng)求獲取配置,比如支付場(chǎng)景中前段JS輪詢訂單支付狀態(tài)。

這樣的壞處顯而易見(jiàn),由于配置數(shù)據(jù)并不會(huì)頻繁變更,若是一直發(fā)請(qǐng)求,勢(shì)必會(huì)對(duì)服務(wù)端造成很大壓力。還會(huì)造成推送數(shù)據(jù)的延遲,比如:每10s請(qǐng)求一次配置,如果在第11s時(shí)配置更新了,那么推送將會(huì)延遲9s,等待下一次請(qǐng)求。

為了解決短輪詢的問(wèn)題,有了長(zhǎng)輪詢方案。

長(zhǎng)輪詢

長(zhǎng)輪詢可不是什么新技術(shù),它不過(guò)是由服務(wù)端控制響應(yīng)客戶端請(qǐng)求的返回時(shí)間,來(lái)減少客戶端無(wú)效請(qǐng)求的一種優(yōu)化手段,其實(shí)對(duì)于客戶端來(lái)說(shuō)與短輪詢的使用并沒(méi)有本質(zhì)上的區(qū)別。

客戶端發(fā)起請(qǐng)求后,服務(wù)端不會(huì)立即返回請(qǐng)求結(jié)果,而是將請(qǐng)求掛起等待一段時(shí)間,如果此段時(shí)間內(nèi)服務(wù)端數(shù)據(jù)變更,立即響應(yīng)客戶端請(qǐng)求,若是一直無(wú)變化則等到指定的超時(shí)時(shí)間后響應(yīng)請(qǐng)求,客戶端重新發(fā)起長(zhǎng)鏈接。

Nacos初識(shí)

為了后續(xù)演示操作方便我在本地搭了個(gè)Nacos注意: 運(yùn)行時(shí)遇到個(gè)小坑,由于Nacos默認(rèn)是以cluster集群的方式啟動(dòng),而本地搭建通常是單機(jī)模式standalone,這里需手動(dòng)改一下啟動(dòng)腳本startup.X中的啟動(dòng)模式。

直接執(zhí)行/bin/startup.X就可以了,默認(rèn)用戶密碼均是nacos。

幾個(gè)概念

Nacos配置中心的幾個(gè)核心概念:dataId、group、namespace,它們的層級(jí)關(guān)系如下圖:

dataId:是配置中心里最基礎(chǔ)的單元,它是一種key-value結(jié)構(gòu),key通常是我們的配置文件名稱,比如:application.ymlmybatis.xml,而value是整個(gè)文件下的內(nèi)容。

目前支持JSONXMLYAML等多種配置格式。

group:dataId配置的分組管理,比如同在dev環(huán)境下開(kāi)發(fā),但同環(huán)境不同分支需要不同的配置數(shù)據(jù),這時(shí)就可以用分組隔離,默認(rèn)分組DEFAULT_GROUP

namespace:項(xiàng)目開(kāi)發(fā)過(guò)程中肯定會(huì)有dev、test、pro等多個(gè)不同環(huán)境,namespace則是對(duì)不同環(huán)境進(jìn)行隔離,默認(rèn)所有配置都在public里。

架構(gòu)設(shè)計(jì)

下圖簡(jiǎn)要描述了nacos配置中心的架構(gòu)流程。

客戶端、控制臺(tái)通過(guò)發(fā)送Http請(qǐng)求將配置數(shù)據(jù)注冊(cè)到服務(wù)端,服務(wù)端持久化數(shù)據(jù)到Mysql。

客戶端拉取配置數(shù)據(jù),并批量設(shè)置對(duì)dataId的監(jiān)聽(tīng)發(fā)起長(zhǎng)輪詢請(qǐng)求,如服務(wù)端配置項(xiàng)變更立即響應(yīng)請(qǐng)求,如無(wú)數(shù)據(jù)變更則將請(qǐng)求掛起一段時(shí)間,直到達(dá)到超時(shí)時(shí)間。為減少對(duì)服務(wù)端壓力以及保證配置中心可用性,拉取到配置數(shù)據(jù)客戶端會(huì)保存一份快照在本地文件中,優(yōu)先讀取。

這里我省略了比較多的細(xì)節(jié),如鑒權(quán)、負(fù)載均衡、高可用方面的設(shè)計(jì)(其實(shí)這部分才是真正值得學(xué)的,后邊另出文講吧),主要弄清客戶端與服務(wù)端的數(shù)據(jù)交互模式。

下邊我們以Nacos 2.0.1版本源碼分析,2.0以后的版本改動(dòng)較多,和網(wǎng)上的很多資料略有些不同 地址:

https://github.com/alibaba/nacos/releases/tag/2.0.1

客戶端源碼分析

Nacos配置中心的客戶端源碼在nacos-client項(xiàng)目,其中NacosConfigService實(shí)現(xiàn)類是所有操作的核心入口。

說(shuō)之前先了解個(gè)客戶端數(shù)據(jù)結(jié)構(gòu)cacheMap,這里大家重點(diǎn)記住它,因?yàn)樗鼛缀踟灤┝薔acos客戶端的所有操作,由于存在多線程場(chǎng)景為保證數(shù)據(jù)一致性,cacheMap采用了AtomicReference原子變量實(shí)現(xiàn)。

/**
 * groupKey -> cacheData.
 */
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(new HashMap<>());
 

cacheMap是個(gè)Map結(jié)構(gòu),key為groupKey,是由dataId, group, tenant(租戶)拼接的字符串;value為CacheData對(duì)象,每個(gè)dataId都會(huì)持有一個(gè)CacheData對(duì)象。

獲取配置

Nacos獲取配置數(shù)據(jù)的邏輯比較簡(jiǎn)單,先取本地快照文件中的配置,如果本地文件不存在或者內(nèi)容為空,則再通過(guò)HTTP請(qǐng)求從遠(yuǎn)端拉取對(duì)應(yīng)dataId配置數(shù)據(jù),并保存到本地快照中,請(qǐng)求默認(rèn)重試3次,超時(shí)時(shí)間3s。

獲取配置有getConfig()getConfigAndSignListener()這兩個(gè)接口,但getConfig()只是發(fā)送普通的HTTP請(qǐng)求,而getConfigAndSignListener()則多了發(fā)起長(zhǎng)輪詢和對(duì)dataId數(shù)據(jù)變更注冊(cè)監(jiān)聽(tīng)的操作addTenantListenersWithContent()。

@Override
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
    return getConfigInner(namespace, dataId, group, timeoutMs);
}
 
@Override
public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener)
        throws NacosException {
    String content = getConfig(dataId, group, timeoutMs);
    worker.addTenantListenersWithContent(dataId, group, content, Arrays.asList(listener));
    return content;
}

注冊(cè)監(jiān)聽(tīng)

客戶端注冊(cè)監(jiān)聽(tīng),先從cacheMap中拿到dataId對(duì)應(yīng)的CacheData對(duì)象。

public void addTenantListenersWithContent(String dataId, String group, String content,
                                          List<? extends Listener> listeners) throws NacosException {
    group = blank2defaultGroup(group);
    String tenant = agent.getTenant();
    // 1、獲取dataId對(duì)應(yīng)的CacheData,如沒(méi)有則向服務(wù)端發(fā)起長(zhǎng)輪詢請(qǐng)求獲取配置
    CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
    synchronized (cache) {
        // 2、注冊(cè)對(duì)dataId的數(shù)據(jù)變更監(jiān)聽(tīng)
        cache.setContent(content);
        for (Listener listener : listeners) {
            cache.addListener(listener);
        }
        cache.setSyncWithServer(false);
        agent.notifyListenConfig();
    }
}

如沒(méi)有則向服務(wù)端發(fā)起長(zhǎng)輪詢請(qǐng)求獲取配置,默認(rèn)的Timeout時(shí)間為30s,并把返回的配置數(shù)據(jù)回填至CacheData對(duì)象的content字段,同時(shí)用content生成MD5值;再通過(guò)addListener()注冊(cè)監(jiān)聽(tīng)器。

CacheData也是個(gè)出場(chǎng)頻率非常高的一個(gè)類,我們看到除了dataId、group、tenant、content這些相關(guān)的基礎(chǔ)屬性,還有幾個(gè)比較重要的屬性如:listenersmd5(content真實(shí)配置數(shù)據(jù)計(jì)算出來(lái)的md5值),以及注冊(cè)監(jiān)聽(tīng)、數(shù)據(jù)比對(duì)、服務(wù)端數(shù)據(jù)變更通知操作都在這里。

其中listeners是對(duì)dataId所注冊(cè)的所有監(jiān)聽(tīng)器集合,其中的ManagerListenerWrap對(duì)象除了持有Listener監(jiān)聽(tīng)類,還有一個(gè)lastCallMd5字段,這個(gè)屬性很關(guān)鍵,它是判斷服務(wù)端數(shù)據(jù)是否更變的重要條件。

在添加監(jiān)聽(tīng)的同時(shí)會(huì)將CacheData對(duì)象當(dāng)前最新的md5值賦值給ManagerListenerWrap對(duì)象的lastCallMd5屬性。

public void addListener(Listener listener) {
    ManagerListenerWrap wrap =
        (listener instanceof AbstractConfigChangeListener) ? new ManagerListenerWrap(listener, md5, content)
            : new ManagerListenerWrap(listener, md5);
}

看到這對(duì)dataId監(jiān)聽(tīng)設(shè)置就完事了?我們發(fā)現(xiàn)所有操作都圍著cacheMap結(jié)構(gòu)中的CacheData對(duì)象,那么大膽猜測(cè)下一定會(huì)有專門的任務(wù)來(lái)處理這個(gè)數(shù)據(jù)結(jié)構(gòu)。

變更通知

客戶端又是如何感知服務(wù)端數(shù)據(jù)已變更呢?

我們還是從頭看,NacosConfigService類的構(gòu)造器中初始化了一個(gè)ClientWorker,而在ClientWorker類的構(gòu)造器中又啟動(dòng)了一個(gè)線程池來(lái)輪詢cacheMap。

而在executeConfigListen()方法中有這么一段邏輯,檢查cacheMap中dataId的CacheData對(duì)象內(nèi),MD5字段與注冊(cè)的監(jiān)聽(tīng)listener內(nèi)的lastCallMd5值,不相同表示配置數(shù)據(jù)變更則觸發(fā)safeNotifyListener方法,發(fā)送數(shù)據(jù)變更通知。

void checkListenerMd5() {
    for (ManagerListenerWrap wrap : listeners) {
        if (!md5.equals(wrap.lastCallMd5)) {
            safeNotifyListener(dataId, group, content, type, md5, encryptedDataKey, wrap);
        }
    }
}

safeNotifyListener()方法單獨(dú)起線程,向所有對(duì)dataId注冊(cè)過(guò)監(jiān)聽(tīng)的客戶端推送變更后的數(shù)據(jù)內(nèi)容。

客戶端接收通知,直接實(shí)現(xiàn)receiveConfigInfo()方法接收回調(diào)數(shù)據(jù),處理自身業(yè)務(wù)就可以了。

configService.addListener(dataId, group, new Listener() {
    @Override
    public void receiveConfigInfo(String configInfo) {
        System.out.println("receive:" + configInfo);
    }
 
    @Override
    public Executor getExecutor() {
        return null;
    }
});

為了理解更直觀我用測(cè)試demo演示下,獲取服務(wù)端配置并設(shè)置監(jiān)聽(tīng),每當(dāng)服務(wù)端配置數(shù)據(jù)變化,客戶端監(jiān)聽(tīng)都會(huì)收到通知,一起看下效果。

public static void main(String[] args) throws NacosException, InterruptedException {
    String serverAddr = "localhost";
    String dataId = "test";
    String group = "DEFAULT_GROUP";
    Properties properties = new Properties();
    properties.put("serverAddr", serverAddr);
    ConfigService configService = NacosFactory.createConfigService(properties);
    String content = configService.getConfig(dataId, group, 5000);
    System.out.println(content);
    configService.addListener(dataId, group, new Listener() {
        @Override
        public void receiveConfigInfo(String configInfo) {
            System.out.println("數(shù)據(jù)變更 receive:" + configInfo);
        }
        @Override
        public Executor getExecutor() {
            return null;
        }
    });
 
    boolean isPublishOk = configService.publishConfig(dataId, group, "我是新配置內(nèi)容~");
    System.out.println(isPublishOk);
 
    Thread.sleep(3000);
    content = configService.getConfig(dataId, group, 5000);
    System.out.println(content);
}

結(jié)果和預(yù)想的一樣,當(dāng)向服務(wù)端publishConfig數(shù)據(jù)變化后,客戶端可以立即感知,愣是用主動(dòng)拉pull模式做出了服務(wù)端實(shí)時(shí)推送的效果。

數(shù)據(jù)變更 receive:我是新配置內(nèi)容~
true
我是新配置內(nèi)容~

服務(wù)端源碼分析

Nacos配置中心的服務(wù)端源碼主要在nacos-config項(xiàng)目的ConfigController類,服務(wù)端的邏輯要比客戶端稍復(fù)雜一些,這里我們重點(diǎn)看下。

處理長(zhǎng)輪詢

服務(wù)端對(duì)外提供的監(jiān)聽(tīng)接口地址/v1/cs/configs/listener,這個(gè)方法內(nèi)容不多,順著doPollingConfig往下看。

服務(wù)端根據(jù)請(qǐng)求header中的Long-Pulling-Timeout屬性來(lái)區(qū)分請(qǐng)求是長(zhǎng)輪詢還是短輪詢,這里咱們只關(guān)注長(zhǎng)輪詢部分,接著看LongPollingService(記住這個(gè)service很關(guān)鍵)類中的addLongPollingClient()方法是如何處理客戶端的長(zhǎng)輪詢請(qǐng)求的。

正常客戶端默認(rèn)設(shè)置的請(qǐng)求超時(shí)時(shí)間是30s,但這里我們發(fā)現(xiàn)服務(wù)端“偷偷”的給減掉了500ms,現(xiàn)在超時(shí)時(shí)間只剩下了29.5s,那為什么要這樣做呢?

用官方的解釋之所以要提前500ms響應(yīng)請(qǐng)求,為了最大程度上保證客戶端不會(huì)因?yàn)榫W(wǎng)絡(luò)延時(shí)造成超時(shí),考慮到請(qǐng)求可能在負(fù)載均衡時(shí)會(huì)耗費(fèi)一些時(shí)間,畢竟Nacos最初就是按照阿里自身業(yè)務(wù)體量設(shè)計(jì)的嘛!

此時(shí)對(duì)客戶端提交上來(lái)的groupkey的MD5與服務(wù)端當(dāng)前的MD5比對(duì),如md5值不同,則說(shuō)明服務(wù)端的配置項(xiàng)發(fā)生過(guò)變更,直接將該groupkey放入changedGroupKeys集合并返回給客戶端。

MD5Util.compareMd5(req, rsp, clientMd5Map)

如未發(fā)生變更,則將客戶端請(qǐng)求掛起,這個(gè)過(guò)程先創(chuàng)建一個(gè)名為ClientLongPolling的調(diào)度任務(wù)Runnable,并提交給scheduler定時(shí)線程池延后29.5s執(zhí)行。

ConfigExecutor.executeLongPolling(
                new ClientLongPolling(asyncContext, clientMd5Map, ip, probeRequestSize, timeout, appName, tag));

這里每個(gè)長(zhǎng)輪詢?nèi)蝿?wù)攜帶了一個(gè)asyncContext對(duì)象,使得每個(gè)請(qǐng)求可以延遲響應(yīng),等延時(shí)到達(dá)或者配置有變更之后,調(diào)用asyncContext.complete()響應(yīng)完成。

asyncContext 為 Servlet 3.0新增的特性,異步處理,使Servlet線程不再需要一直阻塞,等待業(yè)務(wù)處理完畢才輸響應(yīng);可以先釋放容器分配給請(qǐng)求的線程與相關(guān)資源,減輕系統(tǒng)負(fù)擔(dān),其響應(yīng)將被延后,在處理完業(yè)務(wù)或者運(yùn)算后再對(duì)客戶端進(jìn)行響應(yīng)。

ClientLongPolling任務(wù)被提交進(jìn)入延遲線程池執(zhí)行的同時(shí),服務(wù)端會(huì)通過(guò)一個(gè)allSubs隊(duì)列保存所有正在被掛起的客戶端長(zhǎng)輪詢請(qǐng)求任務(wù),這個(gè)是客戶端注冊(cè)監(jiān)聽(tīng)的過(guò)程。

如延時(shí)期間客戶端據(jù)數(shù)一直未變化,延時(shí)時(shí)間到達(dá)后將本次長(zhǎng)輪詢?nèi)蝿?wù)從allSubs隊(duì)列剔除,并響應(yīng)請(qǐng)求response,這是取消監(jiān)聽(tīng)。收到響應(yīng)后客戶端再次發(fā)起長(zhǎng)輪詢,循環(huán)往復(fù)。

處理長(zhǎng)輪詢

到這我們知道服務(wù)端是如何掛起客戶端長(zhǎng)輪詢請(qǐng)求的,一旦請(qǐng)求在掛起期間,用戶通過(guò)管理平臺(tái)操作了配置項(xiàng),或者服務(wù)端收到了來(lái)自其他客戶端節(jié)點(diǎn)修改配置的請(qǐng)求。

怎么能讓對(duì)應(yīng)已掛起的任務(wù)立即取消,并且及時(shí)通知客戶端數(shù)據(jù)發(fā)生了變更呢?

數(shù)據(jù)變更

管理平臺(tái)或者客戶端更改配置項(xiàng)接位置ConfigController中的publishConfig方法。

值得注意得是,在publishConfig接口中有這么一段邏輯,某個(gè)dataId配置數(shù)據(jù)被修改時(shí)會(huì)觸發(fā)一個(gè)數(shù)據(jù)變更事件Event。

ConfigChangePublisher.notifyConfigChange(new ConfigDataChangeEvent(false, dataId, group, tenant, time.getTime()));

仔細(xì)看LongPollingService會(huì)發(fā)現(xiàn)在它的構(gòu)造方法中,正好訂閱了數(shù)據(jù)變更事件,并在事件觸發(fā)時(shí)執(zhí)行一個(gè)數(shù)據(jù)變更調(diào)度任務(wù)DataChangeTask。

訂閱數(shù)據(jù)變更事件

DataChangeTask內(nèi)的主要邏輯就是遍歷allSubs隊(duì)列,上邊我們知道,這個(gè)隊(duì)列中維護(hù)的是所有客戶端的長(zhǎng)輪詢請(qǐng)求任務(wù),從這些任務(wù)中找到包含當(dāng)前發(fā)生變更的groupkeyClientLongPolling任務(wù),以此實(shí)現(xiàn)數(shù)據(jù)更變推送給客戶端,并從allSubs隊(duì)列中剔除此長(zhǎng)輪詢?nèi)蝿?wù)。

DataChangeTask

而我們?cè)诳唇o客戶端響應(yīng)response時(shí),調(diào)用asyncContext.complete()結(jié)束了異步請(qǐng)求。

結(jié)束語(yǔ)

上邊只揭開(kāi)了nacos配置中心的冰山一角,實(shí)際上還有非常多重要的技術(shù)細(xì)節(jié)都沒(méi)提及到,建議大家沒(méi)事看看源碼,源碼不需要通篇的看,只要抓住核心部分就夠了。就比如今天這個(gè)題目以前我真沒(méi)太在意,突然被問(wèn)一下子吃不準(zhǔn)了,果斷看下源碼,而且這樣記憶比較深刻(別人嚼碎了喂你的知識(shí)總是比自己咀嚼的差那么點(diǎn)意思)。

nacos的源碼我個(gè)人覺(jué)得還是比較樸素的,代碼并沒(méi)有過(guò)多炫技,看起來(lái)相對(duì)輕松。大家不要對(duì)看源碼有什么抵觸,它也不過(guò)是別人寫的業(yè)務(wù)代碼而已,just so so!

以上就是阿里面試Nacos配置中心交互模型是push還是pull原理解析的詳細(xì)內(nèi)容,更多關(guān)于Nacos配置中心交互模型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入了解Spring中最常用的11個(gè)擴(kuò)展點(diǎn)

    深入了解Spring中最常用的11個(gè)擴(kuò)展點(diǎn)

    我們一說(shuō)到spring,可能第一個(gè)想到的是?IOC(控制反轉(zhuǎn))?和?AOP(面向切面編程)。除此之外,我們?cè)谑褂胹pring的過(guò)程中,有沒(méi)有發(fā)現(xiàn)它的擴(kuò)展能力非常強(qiáng)。今天就來(lái)跟大家一起聊聊,在Spring中最常用的11個(gè)擴(kuò)展點(diǎn)
    2022-09-09
  • Spring?IOC容器使用詳細(xì)講解

    Spring?IOC容器使用詳細(xì)講解

    IOC-Inversion?of?Control,即控制反轉(zhuǎn)。它不是什么技術(shù),而是一種設(shè)計(jì)思想。這篇文章將為大家介紹一下Spring控制反轉(zhuǎn)IOC的原理,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-12-12
  • Springboot整合Redis的詳細(xì)教程分享

    Springboot整合Redis的詳細(xì)教程分享

    這篇文章主要為大家詳細(xì)介紹了如何利用SpringBoot整合Redis,文中的示例代碼講解詳細(xì),具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2022-08-08
  • 關(guān)于springboot打包目錄全解析

    關(guān)于springboot打包目錄全解析

    這篇文章主要介紹了springboot打包目錄解析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • springboot使用@Slf4j進(jìn)行日志的記錄步驟詳解

    springboot使用@Slf4j進(jìn)行日志的記錄步驟詳解

    這篇文章主要介紹了springboot使用@Slf4j進(jìn)行日志的記錄,使用@Slf4j的注解進(jìn)行日志記錄非常方便,本文給大家分享操作步驟,需要的朋友可以參考下
    2023-08-08
  • 詳解Java的位操作符

    詳解Java的位操作符

    位操作就是對(duì)這些數(shù)據(jù)進(jìn)行基本的操作。如果基本類型是char、byte或者short類型的數(shù)值進(jìn)行移位處理,那么會(huì)轉(zhuǎn)化成int類型,再進(jìn)行移位的處理
    2017-09-09
  • Java Runnable線程傳參,實(shí)現(xiàn)讓run訪問(wèn)參數(shù)

    Java Runnable線程傳參,實(shí)現(xiàn)讓run訪問(wèn)參數(shù)

    這篇文章主要介紹了Java Runnable線程傳參,實(shí)現(xiàn)讓run訪問(wèn)參數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring事務(wù)傳播行為問(wèn)題解決

    Spring事務(wù)傳播行為問(wèn)題解決

    這篇文章主要介紹了Spring事務(wù)傳播行為問(wèn)題解決,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • java使用Stream流對(duì)自定義對(duì)象數(shù)組去重的實(shí)現(xiàn)

    java使用Stream流對(duì)自定義對(duì)象數(shù)組去重的實(shí)現(xiàn)

    本文主要介紹了java使用Stream流對(duì)自定義對(duì)象數(shù)組去重的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Java中@JSONField注解用法、場(chǎng)景與實(shí)踐詳解

    Java中@JSONField注解用法、場(chǎng)景與實(shí)踐詳解

    這篇文章主要給大家介紹了關(guān)于Java中@JSONField注解用法、場(chǎng)景與實(shí)踐的相關(guān)資料,并結(jié)合實(shí)際應(yīng)用場(chǎng)景,幫助開(kāi)發(fā)者在項(xiàng)目中更高效地處理JSON數(shù)據(jù),文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-12-12

最新評(píng)論

南京市| 靖宇县| 禄劝| 南澳县| 庆城县| 蒙山县| 延川县| 余庆县| 神农架林区| 正定县| 辽阳市| 开平市| 垣曲县| 友谊县| 和田县| 常熟市| 象州县| 昔阳县| 敦化市| 那曲县| 屏东县| 平潭县| 阳新县| 四川省| 通江县| 潞西市| 如东县| 安塞县| 贵州省| 繁峙县| 成都市| 乐安县| 乡宁县| 兴宁市| 邵阳市| 怀远县| 屯留县| 云和县| 平果县| 万载县| 绥江县|