精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Nacos配置中心交互模型是 Push 還是 Pull ?

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

[[408988]]

本文轉(zhuǎn)載自微信公眾號(hào)「程序員內(nèi)點(diǎn)事」,作者程序員內(nèi)點(diǎn)事。轉(zhuǎn)載本文請(qǐng)聯(lián)系程序員內(nèi)點(diǎn)事公眾號(hào)。

大家好,我是小富~

對(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)拉的?

[[408989]]

這里我先拋出答案:客戶端主動(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)配置的方式,也就是把配置信息都寫(xiě)在應(yīng)用內(nèi)的yml或properties這類(lèi)文件中,如果要想修改某個(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ù)配置?很顯然這不可能。所以為了解決此類(lèi)問(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ù)變更這類(lèi)邏輯的處理。

弊端:長(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.yml、mybatis.xml,而value是整個(gè)文件下的內(nèi)容。

目前支持JSON、XML、YAML等多種配置格式。

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)類(lèi)是所有操作的核心入口。

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

  1. /** 
  2.  * groupKey -> cacheData. 
  3.  */ 
  4. 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。

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

  1. @Override 
  2. public String getConfig(String dataId, String group, long timeoutMs) throws NacosException { 
  3.     return getConfigInner(namespace, dataId, group, timeoutMs); 
  4.  
  5. @Override 
  6. public String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) 
  7.         throws NacosException { 
  8.     String content = getConfig(dataId, group, timeoutMs); 
  9.     worker.addTenantListenersWithContent(dataId, group, content, Arrays.asList(listener)); 
  10.     return content; 

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

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

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

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

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

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

  1. public void addListener(Listener listener) { 
  2.     ManagerListenerWrap wrap = 
  3.         (listener instanceof AbstractConfigChangeListener) ? new ManagerListenerWrap(listener, md5, content) 
  4.             : new ManagerListenerWrap(listener, md5); 

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

變更通知

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

我們還是從頭看,NacosConfigService類(lèi)的構(gòu)造器中初始化了一個(gè)ClientWorker,而在ClientWorker類(lèi)的構(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ù)變更通知。

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

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

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

  1. configService.addListener(dataId, group, new Listener() { 
  2.     @Override 
  3.     public void receiveConfigInfo(String configInfo) { 
  4.         System.out.println("receive:" + configInfo); 
  5.     } 
  6.  
  7.     @Override 
  8.     public Executor getExecutor() { 
  9.         return null
  10.     } 
  11. }); 

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

  1. public static void main(String[] args) throws NacosException, InterruptedException { 
  2.     String serverAddr = "localhost"
  3.     String dataId = "test"
  4.     String group = "DEFAULT_GROUP"
  5.     Properties properties = new Properties(); 
  6.     properties.put("serverAddr", serverAddr); 
  7.     ConfigService configService = NacosFactory.createConfigService(properties); 
  8.     String content = configService.getConfig(dataId, group, 5000); 
  9.     System.out.println(content); 
  10.     configService.addListener(dataId, group, new Listener() { 
  11.         @Override 
  12.         public void receiveConfigInfo(String configInfo) { 
  13.             System.out.println("數(shù)據(jù)變更 receive:" + configInfo); 
  14.         } 
  15.         @Override 
  16.         public Executor getExecutor() { 
  17.             return null
  18.         } 
  19.     }); 
  20.  
  21.     boolean isPublishOk = configService.publishConfig(dataId, group"我是新配置內(nèi)容~"); 
  22.     System.out.println(isPublishOk); 
  23.  
  24.     Thread.sleep(3000); 
  25.     content = configService.getConfig(dataId, group, 5000); 
  26.     System.out.println(content); 

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

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

服務(wù)端源碼分析

Nacos配置中心的服務(wù)端源碼主要在nacos-config項(xiàng)目的ConfigController類(lèi),服務(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)鍵)類(lèi)中的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集合并返回給客戶端。

  1. MD5Util.compareMd5(req, rsp, clientMd5Map) 

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

  1. ConfigExecutor.executeLongPolling( 
  2.                 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。

  1. 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ā)生變更的groupkey的ClientLongPolling任務(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ò)是別人寫(xiě)的業(yè)務(wù)代碼而已,just so so!

 

責(zé)任編輯:武曉燕 來(lái)源: 程序員內(nèi)點(diǎn)事
相關(guān)推薦

2023-11-17 09:02:51

Nacos配置中心

2021-06-10 06:57:39

Nacos配置模塊

2021-08-09 07:58:36

Nacos 服務(wù)注冊(cè)源碼分析

2022-06-13 09:58:06

NacosSpring

2024-12-10 08:27:28

2021-09-02 09:51:32

監(jiān)控系統(tǒng)分布式

2022-08-29 06:27:15

Nacos微服務(wù)

2021-06-29 07:04:38

Nacos服務(wù)配置

2022-08-30 22:12:19

Nacos組件服務(wù)注冊(cè)

2018-11-15 15:03:59

安全運(yùn)營(yíng)中心SOC數(shù)據(jù)泄露

2021-08-02 07:35:19

Nacos配置中心namespace

2023-08-03 08:51:07

2025-03-03 10:27:33

配置中心微服務(wù)架構(gòu)

2023-10-16 16:14:32

數(shù)據(jù)中心

2021-02-10 09:54:15

分布式NacosApollo

2022-05-09 11:15:05

RocketMQPULL 模式PUSH 模式

2012-08-13 10:52:20

控制數(shù)據(jù)中心

2015-11-27 14:39:26

數(shù)據(jù)中心擴(kuò)張計(jì)劃

2024-09-03 15:57:41

2023-03-01 08:15:10

NginxNacos
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

中文字幕中文字幕99| 欧美与欧洲交xxxx免费观看| 日本黄大片一区二区三区| 91社区在线观看播放| 国产在线一区二区综合免费视频| 欧美大片在线看| 黄色工厂在线观看| 视频欧美精品| 欧美日韩国产激情| 亚洲高清不卡一区| 黄色片一区二区| 美腿丝袜亚洲一区| 97精品视频在线观看| 女教师淫辱の教室蜜臀av软件| 日韩三级久久| 欧美少妇性性性| 福利视频一区二区三区四区| 成人在线免费电影| 不卡大黄网站免费看| 国产中文字幕日韩| 久久99国产综合精品免费| 亚洲天堂免费| 国产亚洲精品美女| 日韩无码精品一区二区| 欧美亚洲福利| 色狠狠一区二区| 日韩精品综合在线| 激情在线小视频| 久久精品一区蜜桃臀影院| www.成人av.com| 亚洲一区二区人妻| 久久久久久色| 91av视频在线免费观看| 久久97人妻无码一区二区三区| 国产探花一区二区| 日韩精品一二三四区| 成人做爰69片免费| 国产一区二区三区| 欧美日韩一级片在线观看| 欧洲av无码放荡人妇网站| 四季久久免费一区二区三区四区| 国产精品久久久久一区二区三区共| 久久草视频在线看| 国模私拍视频在线| 国产成人综合亚洲91猫咪| 成人av资源在线播放| 中文字幕一区二区久久人妻| 免费一区视频| 青草成人免费视频| 国产成人无码精品久久久久| 精品福利av| 欧美激情精品久久久久久蜜臀| 日日噜噜夜夜狠狠久久波多野| 国产99久久| 亚洲性av网站| 欧美偷拍一区二区三区| 国产一区二区在线| 亚洲色图35p| 精品人妻一区二区三区蜜桃视频| 欧美网色网址| 亚洲男人av电影| japanese中文字幕| 国内成人精品| 正在播放国产一区| 污污视频网站在线免费观看| 日本不卡电影| 久久视频在线免费观看| 日韩在线中文字幕视频 | 久久国产日韩欧美| 亚洲aⅴ在线观看| 久久先锋资源网| 日产精品高清视频免费| 99精品老司机免费视频| 亚洲欧洲精品成人久久奇米网| 天天爱天天做天天操| 91精品国产91久久久久久青草| 亚洲女厕所小便bbb| www.亚洲成人网| 忘忧草在线日韩www影院| 色婷婷精品大在线视频| 午夜宅男在线视频| 亚洲1区在线观看| 亚洲电影成人av99爱色| 白白色免费视频| 97在线精品| 久久人人爽人人爽人人片av高请| 天天综合天天干| 蜜臀va亚洲va欧美va天堂| 91在线免费看网站| 特黄aaaaaaaaa真人毛片| 国产人妖乱国产精品人妖| 中文视频一区视频二区视频三区| 一色桃子av在线| 五月综合激情网| 男女视频在线看| 成人高潮a毛片免费观看网站| 亚洲精品综合精品自拍| 久草视频手机在线| 久久av在线| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 疯狂蹂躏欧美一区二区精品| 亚洲欧美自拍另类日韩| 国产精品流白浆在线观看| 亚洲欧洲xxxx| 劲爆欧美第一页| 日韩av中文在线观看| 91精品久久久久久蜜桃| 国产在线你懂得| 亚洲精品视频在线观看免费| 999香蕉视频| 538任你躁精品视频网免费| 一本久久综合亚洲鲁鲁| 成人免费看片98| 日本vs亚洲vs韩国一区三区| 成人在线观看av| 免费人成在线观看播放视频| 欧美性猛交视频| 国产大学生av| 国产精品99久久精品| 欧美亚洲日本网站| 成人毛片视频免费看| 一区精品在线播放| 国产天堂在线播放| 加勒比色老久久爱综合网| 欧美成人在线免费| 国产尤物在线观看| 久久精品免费在线观看| 欧美久久久久久久久久久久久| 四虎国产精品永久在线国在线| 亚洲欧美变态国产另类| 日韩欧美亚洲视频| 国产成人免费在线观看| 日本三级福利片| 九九久久国产| 亚洲新声在线观看| 波多野结衣影片| 久久亚洲一区二区三区四区| 少妇人妻无码专区视频| 日韩一级淫片| 欧美剧在线观看| 国产黄色美女视频| 综合激情成人伊人| 五月天激情播播| 99re久久最新地址获取| 国产精品日韩av| 成年女人的天堂在线| 91国产丝袜在线播放| 不卡一区二区在线观看| 国产精品久久久久毛片大屁完整版 | 欧美日韩乱国产| 91麻豆蜜桃一区二区三区| 一女被多男玩喷潮视频| 日韩mv欧美mv国产网站| 欧美亚洲伦理www| 黄色网址在线播放| 欧美午夜不卡在线观看免费| 四虎成人免费影院| 开心九九激情九九欧美日韩精美视频电影 | 在线观看免费av网址| 999精品在线| 91九色露脸| 激情在线视频播放| 精品av久久707| 欧美日韩精品区| 国产日韩欧美一区二区三区综合| 91av俱乐部| 国产精品7m凸凹视频分类| av色综合网| 免费一二一二在线视频| 国产香蕉一区二区三区在线视频 | 亚洲国产精品电影| 国产午夜性春猛交ⅹxxx| 国产亚洲欧美一级| 日本中文字幕观看| 在线精品一区二区| 欧美影视一区二区| 亚洲老司机网| 久久久视频在线| 国产露出视频在线观看| 欧美日韩性生活| 青青草成人免费| 久久夜色精品一区| www.五月天色| 国产视频一区在线观看一区免费| 日本一区二区在线视频观看| 99久热在线精品视频观看| 久久久久中文字幕2018| 精彩国产在线| 日韩欧美一二三区| 无码人妻精品一区二区三区不卡 | 精品视频在线播放| 亚洲视频一区在线播放| 亚洲成人免费视| 国产在线综合视频| 粉嫩在线一区二区三区视频| 欧美 国产 小说 另类| 亚洲成人精品| 久久另类ts人妖一区二区| 99er精品视频| 国产精品91久久久| 蜜桃传媒在线观看免费进入| 尤物九九久久国产精品的分类| 国产三级第一页| 在线观看中文字幕不卡| 久久精品国产亚洲av麻豆色欲| 国产视频一区在线观看| 美女扒开腿免费视频| 老司机免费视频一区二区三区| 免费看黄在线看| 久久久久久久久丰满| 免费看成人片| 粉嫩av一区二区| 成人福利视频网| 女生影院久久| 国色天香2019中文字幕在线观看| 91精彩在线视频| 亚洲欧美日韩网| 欧美一级淫片免费视频魅影视频| 欧美人动与zoxxxx乱| 国产免费一级视频| 午夜精品久久久久久久99樱桃| 少妇视频一区二区| 国产视频一区二区三区在线观看| 欧美熟妇精品一区二区蜜桃视频| 狠狠色伊人亚洲综合成人| 波多野结衣作品集| 国产一区二区你懂的| 久久99久久99精品| 综合久久亚洲| 中文字幕在线中文字幕日亚韩一区| jiujiure精品视频播放| 精品欧美一区二区久久久伦| 久久综合给合| 147欧美人体大胆444| 美女视频一区| 国产精品爽爽爽爽爽爽在线观看| 亚洲欧美小说色综合小说一区| 久久久影视精品| 欧美人与禽性xxxxx杂性| 美女视频黄免费的亚洲男人天堂| 8888四色奇米在线观看| 在线观看久久久久久| 高清美女视频一区| 在线看日韩欧美| 国产精品毛片一区二区三区四区| 亚洲人成网站色ww在线| 韩日视频在线| 国产亚洲福利一区| 日本亚洲精品| 久久综合亚洲社区| 丝袜在线视频| 欧美黑人视频一区| 成av人片在线观看www| 国模吧一区二区三区| 成年女人在线看片| 国产91精品青草社区| 男人最爱成人网| 国产精品狼人色视频一区| 9999精品视频| 国产精品久久波多野结衣| 理论片一区二区在线| 你懂的网址一区二区三区| 黑人操亚洲人| 在线观看日韩羞羞视频| 女人天堂亚洲aⅴ在线观看| 国产精品久久久久7777| 一区二区毛片| 99视频在线免费| 激情五月激情综合网| 无码人妻精品一区二区三| 91在线观看下载| 亚洲精品一区二区三区影院忠贞| 国产精品美女久久久久久2018| 色偷偷www8888| 亚洲一区二区免费视频| 欧美一区二区三区网站| 欧美日韩免费视频| 亚洲av无码专区在线| 日韩精品在线观| 毛片在线播放a| 国语自产精品视频在线看抢先版图片 | 中文字幕在线一区免费| 久久久久亚洲av片无码下载蜜桃| 精品久久香蕉国产线看观看亚洲| 中文字幕777| 精品少妇一区二区三区| 久久手机免费观看| 久久视频在线免费观看| 女海盗2成人h版中文字幕| 国产精品自拍小视频| 电影一区二区在线观看| 日韩理论片在线观看| 欧美精品播放| 天天天干夜夜夜操| 懂色中文一区二区在线播放| 亚洲精品午夜视频| 亚洲在线成人精品| 99久久久无码国产精品免费蜜柚| 91精品国产综合久久婷婷香蕉| 天堂av电影在线观看| 久久久999国产| 欧美18av| 国产欧美日本在线| 国产国产精品| 日本三区在线观看| 北条麻妃国产九九精品视频| 香蕉久久久久久久| 一本大道av伊人久久综合| 国产免费黄色片| 在线国产精品视频| 热三久草你在线| 99re热精品| 国产精品久久久久蜜臀 | 性欧美大战久久久久久久免费观看| 欧美va天堂在线| 最近中文字幕一区二区| av在线播放一区二区三区| 欧美日韩精品在线观看视频| 欧美日韩亚洲综合一区二区三区| 日本中文字幕一区二区有码在线| 欧美日韩不卡合集视频| 久久久久久久性潮| 色播亚洲婷婷| 亚洲专区免费| 亚洲激情 欧美| 亚洲一级二级在线| 成 人 黄 色 片 在线播放| 日韩小视频在线观看| 日本欧美韩国| 日韩成人在线资源| 久久精品一区二区三区中文字幕| 国产黑丝在线观看| 亚洲国产精品嫩草影院| wwwav在线播放| 欧美成人黑人xx视频免费观看| 色狠狠一区二区三区| 亚洲精品成人自拍| 日本aⅴ精品一区二区三区 | 亚洲人视频在线| 国产精品国产精品国产专区不片| 国产99久久久久久免费看| 亚洲欧美三级伦理| 经典三级一区二区| 神马欧美一区二区| 日韩av一区二区在线影视| 欧美另类z0zx974| 欧美性猛片xxxx免费看久爱 | 操91在线视频| 国产日韩在线观看视频| 亚洲区成人777777精品| 国产一区二区不卡| 免费人成在线观看| 亚洲第一区中文字幕| 蜜臀久久精品| 日韩欧美99| 黄色资源网久久资源365| 亚洲波多野结衣| 日韩久久久精品| 韩日毛片在线观看| 日韩久久久久久久| 韩国理伦片一区二区三区在线播放 | 五月天亚洲一区| 久久久久免费精品| 综合色中文字幕| 国产77777| 国产成人拍精品视频午夜网站| 精品无人区麻豆乱码久久久| www.这里只有精品| 亚洲精品老司机| 水中色av综合| 国产美女精彩久久| 国产精品观看| 亚洲永久精品ww.7491进入| 欧美三级午夜理伦三级中视频| 老司机精品影院| 国产伦精品一区二区三区视频免费| 国产精品毛片在线| 欧美xxxx精品| 精品国产免费一区二区三区香蕉| 亚洲欧美韩国| 只有这里有精品| 久久亚洲私人国产精品va媚药| 国产精品无码久久av| 97人人做人人爱| 91综合在线| 手机在线看片日韩| 欧美精品tushy高清| 波多野结衣中文在线| 日本一区视频在线| 国产v综合v亚洲欧| 国产午夜无码视频在线观看 | 日韩国产精品一区| 四虎影视国产精品| 97av视频在线观看| 亚洲男人电影天堂| 国产小视频在线| 97se国产在线视频| 麻豆国产精品一区二区三区| 久久精品久久国产| 波霸ol色综合久久|