1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        你們想要的Dubbo,三歪搞來了

        共 5739字,需瀏覽 12分鐘

         ·

        2020-05-21 23:21

        本文公眾號(hào)來源:柳樹的絮叨叨

        作者:發(fā)型吃飯的柳樹

        本文已收錄至我的GitHub

        授人以魚,不如授之以漁,其實(shí)這句話說的不只是如何教人。

        從另一個(gè)角度看這句話,我們在學(xué)一樣?xùn)|西的時(shí)候,要找到這樣?xùn)|西的”漁“是什么。

        對于一項(xiàng)技術(shù)來說,它背后的設(shè)計(jì)思想,就是學(xué)習(xí)它的”漁“,對于 Dubbo,”漁“,是微內(nèi)核架構(gòu)。

        首先,我們以「保險(xiǎn)索賠」為例,了解下什么是微內(nèi)核架構(gòu)。

        保險(xiǎn)索賠保險(xiǎn)索賠的規(guī)則往往很復(fù)雜,不同保險(xiǎn)產(chǎn)品、不同地區(qū)的索賠規(guī)則可能都不一樣。

        舉個(gè)例子,假設(shè)在紐約州(NY),汽車擋風(fēng)玻璃被巖石擊碎,是可以索賠的,但是在加利福尼亞州(CA)則不行。這時(shí)候如果直接把這個(gè)邏輯寫到代碼里去,就是這樣:

        
         

        if (在紐約) {
        if (被巖石擊碎) {
        // 索賠...
        }
        } else if (在加利福尼亞) {
        if (被巖石擊碎) {
        // 不索賠...
        }
        }

        而且保險(xiǎn)規(guī)則可不只這一條,到時(shí)候?qū)懗鰜砭褪沁@樣:

        
         

        if (在紐約) {
        if (被巖石擊碎) {
        // 索賠...
        }
        if (被隕石擊碎) {
        // 索賠...
        }
        if (被流星擊碎) {
        // 索賠...
        }
        // more and more...
        } else if (在加利福尼亞) {
        if (被巖石擊碎) {
        // 不索賠...
        }
        if (被隕石擊碎) {
        // 不索賠...
        }
        if (被流星擊碎) {
        // 不索賠...
        }
        // more and more...
        }

        可以看到,我們把索賠規(guī)則的代碼耦合到了索賠的核心系統(tǒng)中:

        4584c943fe39bc78bdc35d0a8d1c85ea.webp

        這會(huì)帶來兩個(gè)問題:

        • 修改索賠規(guī)則需要重新發(fā)布整個(gè)系統(tǒng)

        • 索賠規(guī)則的改動(dòng)可能會(huì)影響整個(gè)系統(tǒng),甚至導(dǎo)致整個(gè)系統(tǒng)不可用

        于是我們把這些規(guī)則抽取出來,有個(gè)專門的地方去管理這些規(guī)則,簡單說,就是「解耦」:

        1c574b42d714348d2658f117418a2f70.webp

        這樣就解決了「耦合度高」的問題,但其實(shí)解耦的還不夠徹底。
        不同州的規(guī)則還是放到一起的,而我們在索賠處理的時(shí)候,每次只需要加載一個(gè)州的索賠規(guī)則,不存在既需要紐約州的規(guī)則,又需要加州規(guī)則的情況

        3befa364c6e09d31969563d6498355c2.webp

        另外,如果后面新來了一個(gè)州,想接入索賠系統(tǒng),那么如何讓這個(gè)州,在不影響其他州的情況下,配置自己的索賠規(guī)則?于是有了這樣一套保險(xiǎn)索賠的「微內(nèi)核架構(gòu)」:

        eb54b382709f81a6f08cbc4f2fe68d63.webp

        簡單說就是,這套系統(tǒng)分兩個(gè)模塊:1、中間的核心模塊處理保險(xiǎn)索賠的基本業(yè)務(wù)邏輯;2、保險(xiǎn)規(guī)則由每個(gè)州自己去實(shí)現(xiàn),做成插件,可以被單獨(dú)加載和移除,不影響核心系統(tǒng)和其他插件。了解完了保險(xiǎn)索賠系統(tǒng)的微內(nèi)核實(shí)現(xiàn),我們再來看看微內(nèi)核架構(gòu),到底是什么。什么是微內(nèi)核架構(gòu)

        Oreilly 對于微內(nèi)核架構(gòu)的定義是這樣的(純英文,大家要再三細(xì)品):

        The microkernel architecture pattern consists of two types of architecture components: a core system and plug-in modules.
        Application logic is divided between independent plug-in modules and the basic core system, providing extensibilityflexibility, and isolation of application features and custom processing logic.

        5956f3ff993b4a8ccc4762b778044b76.webp

        簡單說,就是微內(nèi)核架構(gòu)包含兩個(gè)組件:核心系統(tǒng)(core system)插件模塊(plug-in modules),目的是為了擴(kuò)展性、靈活性和隔離性。核心系統(tǒng)和插件模塊又都有什么職責(zé)呢?
        The core system of the microkernel architecture pattern traditionally contains only the minimal functionality required to make the system operational.
        The plug-in modules are stand-alone, independent components that contain specialized processingadditional features, and custom code that is meant to enhance or extend the core system to produce additional business capabilities.
        核心系統(tǒng)只包含讓系統(tǒng)可以運(yùn)作的最小功能,有點(diǎn)像 MVP(Minimum Viable Product ,最小可用產(chǎn)品)。而插件模塊,則包含一些特殊處理邏輯、額外的功能、自定義代碼,用于強(qiáng)化和擴(kuò)展核心系統(tǒng),提供更多的業(yè)務(wù)能力。這么講還是比較抽象,所以,接下來,進(jìn)入主題,來看看 Dubbo 這個(gè) RPC 框架,是如何基于微內(nèi)核架構(gòu)進(jìn)行設(shè)計(jì)的。什么是 RPC 系統(tǒng)的 core?

        Dubbo 在本質(zhì)上是在解決如何進(jìn)行遠(yuǎn)程調(diào)用(rpc)的問題,通常一個(gè) rpc 系統(tǒng)都長這個(gè)樣子:

        9b9094ea5d2491995cb96ca391d4067a.webp

        但是這些都是一個(gè) rpc 系統(tǒng)所必須的嗎?能不能去掉哪個(gè)模塊后,依然可以進(jìn)行 rpc 調(diào)用?相信大多數(shù)人都可以發(fā)現(xiàn),stub 層是可以去掉的,去掉后,無非你就沒法再進(jìn)行透明式調(diào)用罷了。還有嗎?還有其他哪個(gè)模塊也可以去掉嗎?我們來看一個(gè)極簡的 rpc 調(diào)用:

        c7e79c183a2c19bb013f9ede240a014a.webp

        在這個(gè)例子里,服務(wù)提供方,和服務(wù)消費(fèi)方,是位于同一塊內(nèi)存的:
        • 服務(wù)提供方,暴露服務(wù)時(shí),只需要把自己注冊到一個(gè) map 里
        • 服務(wù)消費(fèi)方,引用服務(wù)時(shí),則只需從 map 里獲取到服務(wù)提供方的引用
        • 當(dāng)服務(wù)消費(fèi)方調(diào)用服務(wù)提供方的方法時(shí),其實(shí)是一次本地內(nèi)存調(diào)用,不涉及什么網(wǎng)絡(luò)傳輸、協(xié)議轉(zhuǎn)換、序列化、反序列化
        大道至簡,當(dāng)我們把 rpc 這個(gè)模型進(jìn)行簡化后,會(huì)發(fā)現(xiàn)其實(shí)這樣就足夠了:

        1818992505ae4dc242d8a41b24e46aac.webp

        其實(shí)這也是 Dubbo 里 inJVM 協(xié)議的實(shí)現(xiàn)原理。當(dāng)然實(shí)際使用中,我們不可能只使用內(nèi)存調(diào)用的 rpc,舉這個(gè)例子,其實(shí)是為了下面介紹 Dubbo 的內(nèi)核。什么是 Dubbo 的 core?

        我們從系統(tǒng)的角度,看看 Dubbo 的整體設(shè)計(jì)圖

        ad99a25e8b6fca9316f43671aaf52983.webp

        這個(gè)是一種傳統(tǒng)的分層視角,每一層都有自己要解決的問題,用 DDD 的話來說,就是每個(gè)域都有自己的問題空間:
        • proxy 層,解決的是:如何實(shí)現(xiàn)服務(wù)接口的透明代理;
        • cluster 層,解決的是:當(dāng)有多個(gè)服務(wù)提供者時(shí),如何調(diào)用、如何負(fù)載均衡等等;
        • 底下三層,也就是 remote 層,解決的是:如何進(jìn)行遠(yuǎn)程調(diào)用;
        按照這個(gè)視角來看,其實(shí)每一層都有自己的 core,每一層都支持通過 SPI 的方式,來實(shí)現(xiàn)擴(kuò)展。但如果我們換個(gè)視角來看,之前說過,Dubbo 本質(zhì)上是為了解決 rpc 的問題,那么其實(shí)我們只需要 protocol 層就足夠了:

        576fbcbced832817f3a0eb70e54da5be.webp

        我們也不必再用傳統(tǒng)的分層架構(gòu)來看,而是換一個(gè)視角:

        4b26d41075c78d44fe52057997e96041.webp

        這個(gè)叫「六邊形架構(gòu)」(Hexagonal Architecture),也叫「端口-適配器架構(gòu)」(Ports and Adapters Architecture),這里就不展開細(xì)講了,有興趣的同學(xué)可以谷歌下。兩種視角的不同就在于,傳統(tǒng)分層視角沒有突出核心和重點(diǎn),你看不出哪一層是必須的,哪一層是整個(gè)架構(gòu)的起源,而六邊形架構(gòu),則一目了然。對于 Dubbo 來說,只有 Protocol 層是核心,是必須的:
        • 當(dāng)你只需要一次 injvm 的 rpc 調(diào)用時(shí),只用 Protocol ,足矣;
        • 如果你需要遠(yuǎn)程調(diào)用,而且有多個(gè)服務(wù)提供方,那需要引入 remote、cluster 和 registry;
        • 如果你還需要透明式的 rpc 調(diào)用,那就再引入 proxy 層
        那么 Protocol 層都做了什么呢,為什么有了它就可以實(shí)現(xiàn)一次 rpc 調(diào)用?Protocol 層如何實(shí)現(xiàn) rpc 調(diào)用?

        Protocol 層,其實(shí)就是上面提到的,一個(gè)最簡化的 rpc 模型:

        c4cd114afc643e83bd16026f9a0810ae.webp

        三個(gè)角色:
        • exporter:對應(yīng)服務(wù)提供方,負(fù)責(zé)把服務(wù)暴露到某個(gè)地方
        • invoker:對應(yīng)服務(wù)消費(fèi)方,從某個(gè)地方引用服務(wù),并調(diào)用服務(wù)
        • protocol:使用什么樣的 protocol,決定了會(huì)有什么樣的 invoker 和 exporter
        很明顯,核心角色是 protocol,比如你采用 injvm 協(xié)議,那就會(huì)生成 InjvmInvoker 和 InjvmExporter:

        d620e85b498fd633611fd4a80dbd2aeb.webp

        而如果你采用的是 dubbo 協(xié)議,則會(huì)生成 DubboInvoker 和 DubboExporter:

        22332881520ad822fcb30374b94ca772.webp

        仔細(xì)看代碼,你會(huì)發(fā)現(xiàn),dubbo 協(xié)議的 refer 方法,會(huì)把 invoker 放進(jìn)一個(gè) invokers 集合里,injvm 協(xié)議的 refer 方法,則直接 new 一個(gè) invoker 后就返回了,說明前者是有可能存在多個(gè)服務(wù)提供者的,而后者只會(huì)有一個(gè)。
        而這些細(xì)節(jié)上的差異,追溯到根源,就是你用了什么樣的協(xié)議(protocol)。
        在 RPC 中,Protocol 是核心層,也就是只要有 Protocol + Invoker + Exporter 就可以完成非透明的 RPC 調(diào)用?!?from Dubbo 框架設(shè)計(jì)
        微內(nèi)核架構(gòu)的其他使用

        除了上面提到的保險(xiǎn)索賠、Dubbo,微內(nèi)核架構(gòu)還被用到很多地方。

        其實(shí)微內(nèi)核架構(gòu)的起源,是操作系統(tǒng):

        8bf32edf6057ed13177e367b45d8760c.webp

        左邊是 Microkernel,右邊是與之對應(yīng)的 Monolithic Kernel,前者只提供最最基礎(chǔ)的操作系統(tǒng)能力,而把更多的能力開放給外界來提供,而后者則傾向于提供一個(gè)大而全的操作系統(tǒng)。
        這里不展開講,大家可以前往維基百科了解下。后來,這種思想逐漸被演變成一種架構(gòu)設(shè)計(jì)模式,于是有了「微內(nèi)核架構(gòu)」。它被用在了許多客戶端應(yīng)用,像 Chrome 瀏覽器:

        e3d73f97ea58cedcb90c9676dce93cca.webp

        Eclipse 編輯器:

        dce3fab79e0795b85640b6e383a52b78.webp

        Chrome 核心就是一個(gè)瀏覽器,用來瀏覽網(wǎng)頁。你可以給它添加各種各樣的插件,像翻譯插件、廣告屏蔽插件等等;而對于第三方開發(fā)者,則可以給它開發(fā)各種插件。
        Eclipse 也一樣,核心就是一個(gè)編輯器,和記事本沒什么區(qū)別,給它添加各種各樣的插件,像代碼高亮、java 代碼編譯等等,就成了一個(gè)好用的開發(fā)工具;第三方開發(fā)者同樣可以給它開發(fā)各種插件。之后它又被進(jìn)一步用在了一些軟件框架、業(yè)務(wù)系統(tǒng)上,比如今天講到的 Dubbo 和保險(xiǎn)索賠系統(tǒng)。甚至在之后的「六邊形架構(gòu)」、DDD 上,都可以看到「微內(nèi)核架構(gòu)」的影子,這兩種設(shè)計(jì)思想被大量用到各種框架、中間件的設(shè)計(jì)上,比如有贊的 MAXIM 全鏈路壓測引擎

        1e79166f6d6ca9312dbc73a5e9fe5bfe.webp

        你可以用一兩句話概況這種思想,比如:開閉原則、模板模式、把不變的和變化的隔離等等,但是僅僅通過這種標(biāo)簽式的、高濃縮的、刻板印象的語言就來概況它,未免還是太過缺乏細(xì)節(jié)和激情了。微內(nèi)核架構(gòu)的優(yōu)缺點(diǎn)

        作為一種架構(gòu)設(shè)計(jì)的模式,通常都會(huì)考慮這些問題:

        • 如何降低系統(tǒng)的復(fù)雜度
        • 如何提高系統(tǒng)的可維護(hù)性
        • 如何提高系統(tǒng)的可擴(kuò)展性
        • 如何提高系統(tǒng)的可配置性
        微內(nèi)核架構(gòu)也不例外,它的優(yōu)點(diǎn)很明顯:擴(kuò)展性:高
        • 核心系統(tǒng)和插件是低耦合的,插件可插拔
        健壯性:高
        • 核心系統(tǒng)和插件之間是隔離的,改變也是隔離的
        • 核心系統(tǒng)可以保持穩(wěn)定
        易部署性:高
        • 插件可支持動(dòng)態(tài)添加(熱部署)
        可測試性:高
        • 插件可以獨(dú)立測試
        缺點(diǎn)也有:可伸縮性:低
        • 大部分實(shí)現(xiàn)都是基于產(chǎn)品的(product based),實(shí)現(xiàn)時(shí)不會(huì)考慮高可伸縮性,當(dāng)然這同樣取決于你的實(shí)現(xiàn)方式。
        開發(fā)難度:高
        • 微內(nèi)核架構(gòu)需要深思熟慮的設(shè)計(jì)和契約的規(guī)劃管理,因此實(shí)現(xiàn)起來比較復(fù)雜。
        • 契約的版本機(jī)制、插件的注冊機(jī)制、插件的粒度、插件連接方式的選擇都使得實(shí)現(xiàn)起來是復(fù)雜的。
        開發(fā)難度高這一點(diǎn),從 Dubbo 的擴(kuò)展點(diǎn)重構(gòu)歷程就可以看出來,其實(shí)一開始 Dubbo 并不是我們看到的分層架構(gòu),而是一步一步演進(jìn)過來的,每一步都包含這背后開發(fā)人員的臥薪嘗膽和絞盡腦汁:

        149d660c391dcde21489c29b9aaaaf91.webp

        最后

        授人以魚不如授人以漁,其實(shí)這句古話是有出處的:

        臨河而羨魚,不如歸家織網(wǎng)?!?《淮南子·說林訓(xùn)》
        人類歷史上迸發(fā)過許多璀璨的思想,就像微內(nèi)核架構(gòu)其實(shí)來源于操作系統(tǒng)的微內(nèi)核。我們在回過頭去看的時(shí)候,可以嘲笑他們有些觀念落伍了,但不要忘了一件事,慢一點(diǎn),再慢一點(diǎn),不要錯(cuò)過一些可能閃耀出來的那點(diǎn)星光。參考:
        • Microkernel Architecture

        • Microkernel
        • 微內(nèi)核架構(gòu)詳解
        • Dubbo 框架設(shè)計(jì)
        • Dubbo 擴(kuò)展點(diǎn)重構(gòu)

        各類知識(shí)點(diǎn)總結(jié)

        下面的文章都有對應(yīng)的原創(chuàng)精美PDF,在持續(xù)更新中,可以來找我催更~

        掃碼或者微信搜Java3y 免費(fèi)領(lǐng)取原創(chuàng)思維導(dǎo)圖、精美PDF。在公眾號(hào)回復(fù)「888」領(lǐng)取,PDF內(nèi)容純手打有任何不懂歡迎來問我。


        
         

        原創(chuàng)電子書
        2886e4c7bb0d2c7e5d415741d3ade3f7.webp

        原創(chuàng)思維導(dǎo)圖

        5447ee8c0d4caacc355f1b99867e0ce2.webp


        a00b135a34a892f996bcf9fafa8df566.webp

        1dd1f2fa4e2c8cc48e0c5570cbc8b3ca.webp

        1dd1f2fa4e2c8cc48e0c5570cbc8b3ca.webp

        瀏覽 111
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            我把小三弄的叫床声太大小说 | 久久久久久久久国产精品 | 少妇高潮又黄又爽免费网站 | 青青视频大香蕉 | 国产精品视频福利 | wwwwww日本 | 男人添女人高潮免费网站打开网站 | 日韩美女做爱视频 | 黑人巨大精品欧美一区二区三区 | 黄色的网站在线观看 |