<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Dubbo3.0 阿里大規(guī)模實(shí)踐解析——URL 重構(gòu)

          共 6703字,需瀏覽 14分鐘

           ·

          2022-03-10 03:19

          點(diǎn)擊上方“服務(wù)端思維”,選擇“設(shè)為星標(biāo)

          回復(fù)”669“獲取獨(dú)家整理的精選資料集

          回復(fù)”加群“加入全國(guó)服務(wù)端高端社群「后端圈」


          作者 |?吳治國(guó)
          出品?| 維阿里巴巴中間件
          • ? ? ? 前不久我們?cè)l(fā)表過(guò) Dubbo3.0?在標(biāo)桿企業(yè)實(shí)戰(zhàn)的文章,描述了 Dubbo3.0 在阿里、工商銀行的實(shí)踐過(guò)程、達(dá)成了單機(jī)與集群資源節(jié)省超 50% 的目標(biāo)。作為 HSF2 與 Dubbo2.0 的共同繼任者,Dubbo3.0 的設(shè)計(jì)目標(biāo)是在阿里巴巴全面取代 HSF2 并成為下一代原生服務(wù)框架,在協(xié)議、性能、服務(wù)發(fā)現(xiàn)模型、云原生等多個(gè)方面進(jìn)行了全面升級(jí)。

          • ? ? ? ?目前阿里內(nèi)部電商系統(tǒng)、餓了么、釘釘、達(dá)摩院、阿里云等大量業(yè)務(wù)均已實(shí)現(xiàn)?Dubbo3.0 廣泛升級(jí),社區(qū)用戶(hù)也涵蓋了包括工商銀行、小米、平安健康等眾多企業(yè)。要支撐阿里百萬(wàn)集群級(jí)實(shí)例和雙十一萬(wàn)億級(jí)服務(wù)調(diào)用,性能提升一直是 Dubbo3.0 關(guān)注的重點(diǎn),在本篇文章中,我們將簡(jiǎn)要介紹 Dubbo3.0 性能優(yōu)化的關(guān)鍵一環(huán)——URL 重構(gòu)。


          01

          URL 簡(jiǎn)介

          Aliware

          在闡述地址推送性能的具體優(yōu)化之前,我們有必要先了解一下與之息息相關(guān)的內(nèi)容—— URL。
          01


          定義


          在不談及 Dubbo 時(shí),我們大多數(shù)人對(duì) URL 這個(gè)概念并不會(huì)感到陌生。統(tǒng)一資源定位器 (RFC1738――Uniform Resource Locators (URL))應(yīng)該是最廣為人知的一個(gè) RFC 規(guī)范,它的定義也非常簡(jiǎn)單。
          因特網(wǎng)上的可用資源可以用簡(jiǎn)單字符串來(lái)表示,該文檔就是描述了這種字符串的語(yǔ)法和語(yǔ)義。而這些字符串則被稱(chēng)為:“統(tǒng)一資源定位器”(URL)


          一個(gè)標(biāo)準(zhǔn)的 URL 格式至多可以包含如下的幾個(gè)部分:
          protocol://username:password@host:port/path?key=value&key=value

          一些典型 URL:
          http://www.facebook.com/friends?param1=value1&param2=value2https://username:[email protected]:8080/list?version=1.0.0ftp://username:[email protected]:21/1/read.txt

          當(dāng)然,也有一些不太符合常規(guī)的 URL,也被歸類(lèi)到了 URL 之中:
          192.168.1.3:20880url protocol = null, url host = 192.168.1.3, port = 20880, url path = null
          file:///home/user1/router.js?type=scripturl protocol = file, url host = null, url path = home/user1/router.js
          file://home/user1/router.js?type=script
          url protocol = file, url host = home, url path = user1/router.js
          file:///D:/1/router.js?type=scripturl protocol = file, url host = null, url path = D:/1/router.js
          file:/D:/1/router.js?type=script同上 file:///D:/1/router.js?type=script
          /home/user1/router.js?type=scripturl protocol = null, url host = null, url path = home/user1/router.js
          home/user1/router.js?type=scripturl protocol = null, url host = home, url path = user1/router.js
          02


          Dubbo 中的 URL


          在Dubbo 中,也使用了類(lèi)似的 URL,主要用于在各個(gè)擴(kuò)展點(diǎn)之間傳遞數(shù)據(jù),組成此 URL 對(duì)象的具體參數(shù)如下:

          • protocol:一般是 Ddubbo 中的各種協(xié)議 如:Dubbo thrift http zk
          • username/password:用戶(hù)名/密碼
          • host/port:主機(jī)/端口
          • path:接口名稱(chēng)
          • parameters:參數(shù)鍵值對(duì)

          一些典型的 Dubbo URL
          dubbo://192.168.1.6:20880/moe.cnkirito.sample.HelloService?timeout=3000描述一個(gè) dubbo 協(xié)議的服務(wù)
          zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=1214&qos.port=33333×tamp=1545721981946描述一個(gè) zookeeper 注冊(cè)中心
          consumer://30.5.120.217/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.2&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=1209&qos.port=33333&side=consumer×tamp=1545721827784描述一個(gè)消費(fèi)者

          可以說(shuō),任意的一個(gè)領(lǐng)域中的一個(gè)實(shí)現(xiàn)都可以認(rèn)為是一類(lèi) URL,Dubbo 使用 URL 來(lái)統(tǒng)一描述了元數(shù)據(jù),配置信息,貫穿在整個(gè)框架之中。

          02

          Dubbo 2.7

          Aliware

          01


          URL 結(jié)構(gòu)


          在 Dubbo 2.7 中,URL 的結(jié)構(gòu)非常簡(jiǎn)單,一個(gè)類(lèi)就涵蓋了所有內(nèi)容,如下圖所示。


          02


          地址推送模型


          接下來(lái)我們?cè)賮?lái)看看 Dubbo 2.7 中的地址推送模型方案,主要性能問(wèn)題由下列過(guò)程引起:


          上圖中主要的流程為:
          1、用戶(hù)新增/刪除 DemoService 的某個(gè)具體 Provider 實(shí)例(常見(jiàn)于擴(kuò)容縮容、網(wǎng)絡(luò)波動(dòng)等原因);
          2、ZooKeeper 將 DemoService 下所有實(shí)例推送給 Consumer 端;
          3、Consumer 端根據(jù) Zookeeper 推送的數(shù)據(jù)重新全量生成 URL。

          根據(jù)該方案可以看出在 Provider 實(shí)例數(shù)量較小時(shí),Consumer 端的影響比較小,但當(dāng)某個(gè)接口有大量 Provider 實(shí)例時(shí),便會(huì)有大量不必要的 URL 創(chuàng)建過(guò)程。

          而 Dubbo 3.0 中則主要針對(duì)上述推送流程進(jìn)行了一系列的優(yōu)化,接下來(lái)我們便對(duì)其進(jìn)行具體的講解。

          03

          Dubbo 3.0

          Aliware

          01


          URL 結(jié)構(gòu)


          當(dāng)然,地址推送模型的優(yōu)化依然離不開(kāi) URL 的優(yōu)化,下圖是 Dubbo 3.0 中優(yōu)化地址推送模型的過(guò)程中使用的新的 URL 結(jié)構(gòu)。


          根據(jù)上圖我們可以看出,在 Dubbo 2.7 的 URL 中的幾個(gè)重要屬性在 Dubbo 3.0 中已經(jīng)不存在了,取而代之的是 URLAddress 和 URLParam 兩個(gè)類(lèi)。原來(lái)的 parameters 屬性被移動(dòng)到了 URLParam 中的 params,其他的屬性則移動(dòng)到了 URLAddress 及其子類(lèi)中。

          再來(lái)介紹 URL 新增的 3 個(gè)子類(lèi),其中 InstanceAddressURL 屬于應(yīng)用級(jí)接口地址,本篇章中不做介紹。

          而 ServiceConfigURL 及 ServiceAddressURL 主要的差別就是,ServiceConfigURL 是程序讀取配置文件時(shí)生成的 URL。而 ServiceAddressURL 則是注冊(cè)中心推送一些信息(如 providers)過(guò)來(lái)時(shí)生成的 URL。

          在這里我們順便提一下為什么會(huì)有 DubboServiceAddressURL 這個(gè)子類(lèi),按照目前的結(jié)構(gòu)來(lái)看,ServiceAddressURL 只有這一個(gè)子類(lèi),所以完全可以將他們兩個(gè)的屬性全都放到 ServiceAddressURL 中,那么為什么還要有這個(gè)子類(lèi)呢?其實(shí)是 Dubbo 3.0 為了兼容 HSF 框架所設(shè)計(jì)的,抽象出了一個(gè) ServiceAddressURL,而 HSF 框架則可以繼承這個(gè)類(lèi),使用 HSFServiceAddressURL,當(dāng)然,這個(gè)類(lèi)目前沒(méi)有體現(xiàn)出來(lái),所以此處我們簡(jiǎn)單一提,不過(guò)多講解。

          那么,我們接下來(lái)就討論一下 Dubbo 3.0 為什么要改為此種數(shù)據(jù)結(jié)構(gòu),并且該結(jié)構(gòu)和地址推送模型的優(yōu)化有何關(guān)聯(lián)性吧!

          02


          地址推送模型的優(yōu)化


          • URL 結(jié)構(gòu)上的優(yōu)化

          我們?cè)谏闲」?jié)中的類(lèi)圖里看到雖然原來(lái)的屬性都被移到了 URLAddress 和 URLParam 里,但是 URL 的子類(lèi)依然多了幾個(gè)屬性,這幾個(gè)屬性自然也是為了優(yōu)化而新增的,那么這里就講講這幾個(gè)屬性的作用。

          ServiceConfigURL:這個(gè)子類(lèi)中新增了 attribute 這個(gè)屬性,這個(gè)屬性主要是針對(duì) URLParam 的 params 做了冗余,僅僅只是將 value 的類(lèi)型從 String 改為了 Object,減少了代碼中每次獲取 parameters 的格式轉(zhuǎn)換消耗。

          ServiceAddressURL:這個(gè)子類(lèi)及其對(duì)應(yīng)的其他子類(lèi)中則新增了 overrideURL 和 consumerURL 屬性。其中 consumerURL 是針對(duì) consumer 端的配置信息,overrideURL 則是在 Dubbo Admin 上進(jìn)行動(dòng)態(tài)配置時(shí)寫(xiě)入的值,當(dāng)我們調(diào)用 URL 的 getParameter() 方法時(shí),優(yōu)先級(jí)為 overrideURL > consumerURL > urlParam。在 Dubbo 2.7 時(shí),動(dòng)態(tài)配置屬性會(huì)替換 URL 中的屬性,及當(dāng)你有大量 URL 時(shí)消耗也是不可忽視的,而此處的 overrideURL 則避免了這種消耗,因?yàn)樗?URL 都會(huì)共同使用同一個(gè)對(duì)象。

          • 多級(jí)緩存

          緩存是 Dubbo 3.0 在 URL 上做的優(yōu)化的重點(diǎn),同時(shí)這部分也是直接針對(duì)地址推送模型所做的優(yōu)化,那么接下來(lái)我們就開(kāi)始來(lái)介紹一下多級(jí)緩存的具體實(shí)現(xiàn)。

          首先,多級(jí)緩存主要體現(xiàn)在 CacheableFailbackRegistry 這個(gè)類(lèi)之中,它直接繼承于 FailbackRegistry,以 Zookeeper 為例,我們看看 Dubbo 2.7 和 Dubbo 3.0 繼承結(jié)構(gòu)的區(qū)別。


          可以看到在 CacheableFailbackRegistry 緩存中,我們新增了 3 個(gè)緩存屬性 stringAddress,stringParam 和 stringUrls。我們通過(guò)下圖來(lái)描述這 3 個(gè)緩存的具體使用場(chǎng)景。


          在該方案下,我們使用了 3 個(gè)緯度的緩存數(shù)據(jù)(URL 字符串緩存、URL 地址緩存、URL 參數(shù)緩存),這樣一來(lái),在大部分情況下都能有效利用到緩存中的數(shù)據(jù),減少了 Zookeeper 重復(fù)通知的消耗。


          • 延遲通知

          除了上面提到的優(yōu)化之外,其實(shí)另外還有兩個(gè)小小的優(yōu)化。

          第一個(gè)是解析 URL 時(shí)可以直接使用編碼后的 URL 字符串字節(jié)進(jìn)行解析,而在 Dubbo 2.7 中,所有編碼后的 URL 字符串都需要經(jīng)過(guò)解碼才可以正常解析為 URL 對(duì)象。該方式也直接減少了 URL 解碼過(guò)程的開(kāi)銷(xiāo)。

          第二個(gè)則是 URL 變更后的通知機(jī)制增加了延遲,下圖以Zookeeper為例講解了實(shí)現(xiàn)細(xì)節(jié)。


          在該方案中,當(dāng) Consumer 接收 Zookeeper 的變更通知后會(huì)主動(dòng)休眠一段時(shí)間,而這段時(shí)間內(nèi)的變更在休眠結(jié)束后只會(huì)保留最后一次變更,Consumer 便會(huì)使用最后一次變更來(lái)進(jìn)行監(jiān)聽(tīng)實(shí)例的更新,以此方法來(lái)減少大量 URL 的創(chuàng)建開(kāi)銷(xiāo)。

          • 字符串重用

          在舊版本實(shí)現(xiàn)中,不同的 URL 中屬性相同的字符串會(huì)存儲(chǔ)在堆內(nèi)不同的地址中,如 protocol、path 等,當(dāng)有大量 provider 的情況下,Consumer 端的堆內(nèi)會(huì)存在大量的重復(fù)字符串,導(dǎo)致內(nèi)存利用率低下,所以此處提供了另一個(gè)優(yōu)化方式,即字符串重用。

          而它的實(shí)現(xiàn)方式也非常的簡(jiǎn)單,讓我們來(lái)看看對(duì)應(yīng)的代碼片段。
          public class URLItemCache {    private static final Map PATH_CACHE = new LRUCache<>(10000);    private static final Map PROTOCOL_CACHE = new ConcurrentHashMap<>();
          // 省略無(wú)關(guān)代碼片段
          public static String checkProtocol(String _protocol) { if (_protocol == null) { return _protocol; } String cachedProtocol = PROTOCOL_CACHE.putIfAbsent(_protocol, _protocol); if (cachedProtocol != null) { return cachedProtocol; } return _protocol; }
          public static String checkPath(String _path) { if (_path == null) { return _path; } String cachedPath = PATH_CACHE.putIfAbsent(_path, _path); if (cachedPath != null) { return cachedPath; } return _path; }}

          由如上代碼片段可以得知,字符串重用即為簡(jiǎn)單地使用了 Map 來(lái)存儲(chǔ)對(duì)應(yīng)的緩存值,當(dāng)你使用了相同的字符串時(shí),便會(huì)從 Map 中獲取早已存在的對(duì)象返回給調(diào)用方,由此便可以減少堆內(nèi)存中重復(fù)的字符串?dāng)?shù)以達(dá)到優(yōu)化的效果。

          03


          優(yōu)化結(jié)果


          這里優(yōu)化結(jié)果我引用了《Dubbo 3.0 前瞻:服務(wù)發(fā)現(xiàn)支持百萬(wàn)集群,帶來(lái)可伸縮微服務(wù)架構(gòu)》這篇文章中的兩副圖來(lái)說(shuō)明,下圖模擬了在 220 萬(wàn)個(gè) Provider 接口的情況下,接口數(shù)據(jù)不斷變更導(dǎo)致的 Consumer 端的消耗,我們看到整個(gè) Consumer 端幾乎被 Full GC 占滿(mǎn)了,嚴(yán)重影響了性能。


          那么我們?cè)賮?lái)看看 Dubbo 3.0 中對(duì) URL 進(jìn)行優(yōu)化后同一個(gè)環(huán)境下的壓測(cè)結(jié)果,如下圖所示。


          我們明顯可以看到 Full GC 的頻率減少到了只有 3 次,大大提升了性能。當(dāng)然,該文章中還有其他方面的對(duì)比,此處便不一一引用了,感興趣的讀者可以自行去閱讀該文章。


          為方便社區(qū)用戶(hù)交流,Dubbo 社區(qū)為 Dubbo3.0?用戶(hù)組建了包括 Github、在內(nèi)的用戶(hù)溝通渠道,感興趣的讀者可自行加入討論,與社區(qū)核心開(kāi)發(fā)者及用戶(hù)交流分享使用經(jīng)驗(yàn)。


          — 本文結(jié)束 —


          ●?漫談設(shè)計(jì)模式在 Spring 框架中的良好實(shí)踐

          ●?顛覆微服務(wù)認(rèn)知:深入思考微服務(wù)的七個(gè)主流觀點(diǎn)

          ●?人人都是 API 設(shè)計(jì)者

          ●?一文講透微服務(wù)下如何保證事務(wù)的一致性

          ●?要黑盒測(cè)試微服務(wù)內(nèi)部服務(wù)間調(diào)用,我該如何實(shí)現(xiàn)?



          關(guān)注我,回復(fù) 「加群」 加入各種主題討論群。



          對(duì)「服務(wù)端思維」有期待,請(qǐng)?jiān)谖哪c(diǎn)個(gè)在看

          喜歡這篇文章,歡迎轉(zhuǎn)發(fā)、分享朋友圈


          在看點(diǎn)這里
          瀏覽 63
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产日韩欧美一区 | 亚洲va欧美va国产va精品 | 吴梦梦无码一区二区三区首发新作 | 丁香婷婷色视频 | 午夜骚逼|