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>

        微服務(wù)面試必問(wèn)的Dubbo,這么詳細(xì)還怕自己找不到工作?

        共 15686字,需瀏覽 32分鐘

         ·

        2021-03-30 16:07

        大家好,我是小羽。

        Dubbo 起源于阿里巴巴,對(duì)于我們做電商開(kāi)發(fā)的人來(lái)說(shuō),基本是首選的技術(shù),那么為何一個(gè)區(qū)區(qū) soa 服務(wù)治理框架,會(huì)受到這么多人的青睞呢?

        今天就跟著小羽一起看看這個(gè)微服務(wù)框架之一的 Dubbo 的詳細(xì)解讀吧。

        前言

        互聯(lián)網(wǎng)的不斷發(fā)展,網(wǎng)站應(yīng)用的規(guī)模不斷擴(kuò)大,常規(guī)的垂直應(yīng)用架構(gòu)已無(wú)法應(yīng)對(duì)。

        服務(wù)化的進(jìn)一步發(fā)展,服務(wù)越來(lái)越多,服務(wù)之間的調(diào)用和依賴(lài)關(guān)系也越來(lái)越復(fù)雜,誕生了面向服務(wù)的架構(gòu)體系(SOA),

        也因此衍生出了一系列相應(yīng)的技術(shù),如對(duì)服務(wù)提供、服務(wù)調(diào)用、連接處理、通信協(xié)議、序列化方式、服務(wù)發(fā)現(xiàn)、服務(wù)路由、日志輸出等行為進(jìn)行封裝的服務(wù)框架。

        就這樣分布式系統(tǒng)的服務(wù)治理框架就出現(xiàn)了,Dubbo也就這樣產(chǎn)生了。

        概念

        Dubbo 是一款高性能、輕量級(jí)的開(kāi)源 RPC 框架、提供服務(wù)自動(dòng)注冊(cè)、自動(dòng)發(fā)現(xiàn)等高效治理方案,可以和 Spring 框架無(wú)縫集成。

        簡(jiǎn)單的說(shuō),dubbo就是個(gè)分布式服務(wù)框架,在有分布式需要的時(shí)候可以使用 dubbo 的框架,使用 dubbo 的好處:

        1、透明化的遠(yuǎn)程方法調(diào)用

        2、軟負(fù)載均衡及容錯(cuò)機(jī)制

        3、服務(wù)自動(dòng)注冊(cè)與發(fā)現(xiàn)

        4、提供了完善的服務(wù)接口管理與監(jiān)控功能

        架構(gòu)圖

        RPC

        簡(jiǎn)介

        RPC 全稱(chēng)為 remote procedure call,即遠(yuǎn)程過(guò)程調(diào)用。比如兩臺(tái)服務(wù)器 A 和 B,A 服務(wù)器上部署一個(gè)應(yīng)用,B 服務(wù)器上部署一個(gè)應(yīng)用,A 服務(wù)器上的應(yīng)用想調(diào)用 B 服務(wù)器上的應(yīng)用提供的方法,由于兩個(gè)應(yīng)用不在一個(gè)內(nèi)存空間,不能直接調(diào)用,所以需要通過(guò)網(wǎng)絡(luò)來(lái)表達(dá)調(diào)用的語(yǔ)義和傳達(dá)調(diào)用的數(shù)據(jù)。

        RPC 并不是一個(gè)具體的技術(shù),而是指整個(gè)網(wǎng)絡(luò)遠(yuǎn)程調(diào)用過(guò)程。

        RPC 是一個(gè)泛化的概念,嚴(yán)格來(lái)說(shuō)一切遠(yuǎn)程過(guò)程調(diào)用手段都屬于 RP C范疇。各種開(kāi)發(fā)語(yǔ)言都有自己的 RPC 框架。Java 中的 RPC 框架比較多,廣泛使用的有 RMI、Hessian、Dubbo 等。

        原理

        服務(wù)消費(fèi)方(client)調(diào)用以本地調(diào)用方式調(diào)用服務(wù)??蛻?hù)端存根(client stub)接收到調(diào)用后負(fù)責(zé)將方法、參數(shù)等編碼成能在網(wǎng)絡(luò)中傳輸?shù)南Ⅲw。然后,客戶(hù)端存根找到服務(wù)地址后,將消息發(fā)送給服務(wù)端。

        服務(wù)提供方(server)收到序列化后的消息,就按照解碼該消息。然后,根據(jù)解碼結(jié)果調(diào)用本地服務(wù),執(zhí)行完畢后,將結(jié)果打包發(fā)送給消費(fèi)方。

        服務(wù)消費(fèi)方收到執(zhí)行結(jié)果后,也是進(jìn)行解碼后得到結(jié)果。

        原理

        使用場(chǎng)景

        RPC 分布式服務(wù),拆分應(yīng)用進(jìn)行服務(wù)化,提高開(kāi)發(fā)效率,調(diào)優(yōu)性能,節(jié)省競(jìng)爭(zhēng)資源

        配置管理,解決服務(wù)的地址信息劇增,配置困難的問(wèn)題

        服務(wù)依賴(lài),解決服務(wù)間依賴(lài)關(guān)系錯(cuò)蹤復(fù)雜的問(wèn)題

        服務(wù)擴(kuò)容,解決隨著訪問(wèn)量的不斷增大,動(dòng)態(tài)擴(kuò)展服務(wù)提供方的機(jī)器的問(wèn)題

        核心功能

        Remoting:遠(yuǎn)程通訊,提供對(duì)多種 NIO 框架抽象封裝,包括“同步轉(zhuǎn)異步”和“請(qǐng)求-響應(yīng)”模式的信息交換方式。

        Cluster:服務(wù)框架,提供基于接口方法的透明遠(yuǎn)程過(guò)程調(diào)用,包括多協(xié)議支持,以及軟負(fù)載均衡,失敗容錯(cuò),地址路由,動(dòng)態(tài)配置等集群支持。

        Registry:服務(wù)注冊(cè)中心,服務(wù)自動(dòng)發(fā)現(xiàn): 基于注冊(cè)中心目錄服務(wù),使服務(wù)消費(fèi)方能動(dòng)態(tài)的查找服務(wù)提供方,使地址透明,使服務(wù)提供方可以平滑增加或減少機(jī)器。

        核心組件

        Provider:服務(wù)的提供方

        Consumer:調(diào)用遠(yuǎn)程服務(wù)的服務(wù)消費(fèi)方

        Registry:服務(wù)注冊(cè)和發(fā)現(xiàn)的注冊(cè)中心

        Monitor:統(tǒng)計(jì)服務(wù)調(diào)用次數(shù)和調(diào)用時(shí)間的監(jiān)控中心

        Container:服務(wù)運(yùn)行容器

        組件

        服務(wù)注冊(cè)與發(fā)現(xiàn)

        流程如下:

        1、Provider(提供者)綁定指定端口并啟動(dòng)服務(wù)

        2、供者連接注冊(cè)中心,并發(fā)本機(jī) IP、端口、應(yīng)用信息和提供服務(wù)信息發(fā)送至注冊(cè)中心存儲(chǔ)

        3、Consumer(消費(fèi)者),連接注冊(cè)中心 ,并發(fā)送應(yīng)用信息、所求服務(wù)信息至注冊(cè)中心

        4、注冊(cè)中心根據(jù)消費(fèi)者所求服務(wù)信息匹配對(duì)應(yīng)的提供者列表發(fā)送至Consumer 應(yīng)用緩存。

        5、Consumer 在發(fā)起遠(yuǎn)程調(diào)用時(shí)基于緩存的消費(fèi)者列表?yè)衿湟话l(fā)起調(diào)用。

        6、Provider 狀態(tài)變更會(huì)實(shí)時(shí)通知注冊(cè)中心、在由注冊(cè)中心實(shí)時(shí)推送至Consumer設(shè)計(jì)的原因:

        Consumer 與 Provider 解偶,雙方都可以橫向增減節(jié)點(diǎn)數(shù)。注冊(cè)中心對(duì)本身可做對(duì)等集群,可動(dòng)態(tài)增減節(jié)點(diǎn),并且任意一臺(tái)宕掉后,將自動(dòng)切換到另一臺(tái)

        7、去中心化,雙方不直接依懶注冊(cè)中心,即使注冊(cè)中心全部宕機(jī)短時(shí)間內(nèi)也不會(huì)影響服務(wù)的調(diào)用

        8、服務(wù)提供者無(wú)狀態(tài),任意一臺(tái)宕掉后,不影響使用

        流程

        服務(wù)治理

        治理原因

        Dubbo的服務(wù)治理主要原因:

        1、過(guò)多的服務(wù) URL 配置困難。

        2、負(fù)載均衡分配節(jié)點(diǎn)壓力過(guò)大的情況下也需要部署集群。

        3、服務(wù)依賴(lài)混亂,啟動(dòng)順序不清晰。

        4、過(guò)多服務(wù)導(dǎo)致性能指標(biāo)分析難度較大,需要監(jiān)控。

        主要特性

        透明遠(yuǎn)程調(diào)用:就像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法;只需簡(jiǎn)單配置,沒(méi)有任何 API 侵入

        負(fù)載均衡機(jī)制:Client 端 LB,可在內(nèi)網(wǎng)替代 F5 等硬件負(fù)載均衡器

        容錯(cuò)重試機(jī)制:服務(wù) Mock 數(shù)據(jù),重試次數(shù)、超時(shí)機(jī)制等

        自動(dòng)注冊(cè)發(fā)現(xiàn):注冊(cè)中心基于接口名查詢(xún)服務(wù)提 供者的 IP 地址,并且能夠平滑添加或刪除服務(wù)提供者

        性能日志監(jiān)控:Monitor 統(tǒng)計(jì)服務(wù)的調(diào)用次調(diào)和調(diào)用時(shí)間的監(jiān)控中心

        服務(wù)治理中心:路由規(guī)則,動(dòng)態(tài)配置,服務(wù)降級(jí),訪問(wèn)控制,權(quán)重調(diào)整,負(fù)載均衡,等手動(dòng)配置

        自動(dòng)治理中心:無(wú),比如:熔斷限流機(jī)制、自動(dòng)權(quán)重調(diào)整等(因此可以搭配SpringCloud的熔斷機(jī)制等進(jìn)行開(kāi)發(fā))

        服務(wù)治理

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

        整體架構(gòu)

        先看下 Dubbo 的整體架構(gòu)圖:

        圖例說(shuō)明:

        整體架構(gòu)

        圖中左邊淡藍(lán)背景的為服務(wù)消費(fèi)方使用的接口,右邊淡綠色背景的為服務(wù)提供方使用的接口,位于中軸線上的為雙方都用到的接口。

        圖中從下至上分為十層,各層均為單向依賴(lài),右邊的黑色箭頭代表層之間的依賴(lài)關(guān)系,每一層都可以剝離上層被復(fù)用,其中,ServiceConfig 層為 API,其它各層均為 SPI。

        圖中綠色小塊的為擴(kuò)展接口,藍(lán)色小塊為實(shí)現(xiàn)類(lèi),圖中只顯示用于關(guān)聯(lián)各層的實(shí)現(xiàn)類(lèi)。

        圖中藍(lán)色虛線為初始化過(guò)程,即啟動(dòng)時(shí)組裝鏈,紅色實(shí)線為方法調(diào)用過(guò)程,即運(yùn)行時(shí)調(diào)時(shí)鏈,紫色三角箭頭為繼承,可以把子類(lèi)看作父類(lèi)的同一個(gè)節(jié)點(diǎn),線上的文字為調(diào)用的方法。

        各層說(shuō)明

        config 配置層:對(duì)外配置接口,以 ServiceConfig, ReferenceConfig 為中心,可以直接初始化配置類(lèi),也可以通過(guò) spring 解析配置生成配置類(lèi)

        proxy 服務(wù)代理層:服務(wù)接口透明代理,生成服務(wù)的客戶(hù)端 Stub 和服務(wù)器端 Skeleton,以ServiceProxy 為中心,擴(kuò)展接口為 ProxyFactory

        registry 注冊(cè)中心層:封裝服務(wù)地址的注冊(cè)與發(fā)現(xiàn),以服務(wù) URL 為中心,擴(kuò)展接口為RegistryFactory, Registry, RegistryService

        cluster 路由層:封裝多個(gè)提供者的路由及負(fù)載均衡,并橋接注冊(cè)中心,以 Invoker 為中心,擴(kuò)展接口為 Cluster, Directory, Router, LoadBalance

        monitor 監(jiān)控層:RPC 調(diào)用次數(shù)和調(diào)用時(shí)間監(jiān)控,以 Statistics 為中心,擴(kuò)展接口為MonitorFactory, Monitor, MonitorService

        protocol 遠(yuǎn)程調(diào)用層:封裝 RPC 調(diào)用,以 Invocation, Result 為中心,擴(kuò)展接口為 Protocol, Invoker, Exporter

        exchange 信息交換層:封裝請(qǐng)求響應(yīng)模式,同步轉(zhuǎn)異步,以 Request, Response 為中心,擴(kuò)展接口為 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer

        transport 網(wǎng)絡(luò)傳輸層:抽象 mina 和 netty 為統(tǒng)一接口,以 Message 為中心,擴(kuò)展接口為 Channel, Transporter, Client, Server, Codec

        serialize 數(shù)據(jù)序列化層:可復(fù)用的一些工具,擴(kuò)展接口為 Serialization, ObjectInput, ObjectOutput, ThreadPool

        主要模塊

        dubbo-common 公共邏輯模塊,包括 Util 類(lèi)和通用模型。

        dubbo-remoting 遠(yuǎn)程通訊模塊,相當(dāng)于 Dubbo 協(xié)議的實(shí)現(xiàn),如果 RPC 用 RMI 協(xié)議則不需要使用此包。

        dubbo-rpc 遠(yuǎn)程調(diào)用模塊,抽象各種協(xié)議,以及動(dòng)態(tài)代理,只包含一對(duì)一的調(diào)用,不關(guān)心集群的管理。

        dubbo-cluster 集群模塊,將多個(gè)服務(wù)提供方偽裝為一個(gè)提供方,包括:負(fù)載均衡、容錯(cuò)、路由等,集群的地址列表可以是靜態(tài)配置的,也可以是由注冊(cè)中心下發(fā)。

        dubbo-registry 注冊(cè)中心模塊,基于注冊(cè)中心下發(fā)地址的集群方式,以及對(duì)各種注冊(cè)中心的抽象。

        dubbo-monitor 監(jiān)控模塊,統(tǒng)計(jì)服務(wù)調(diào)用次數(shù),調(diào)用時(shí)間的,調(diào)用鏈跟蹤的服務(wù)。

        dubbo-config 配置模塊,是 Dubbo 對(duì)外的 API ,用戶(hù)通過(guò) Config 使用 Dubbo ,隱藏 Dubbo 所有細(xì)節(jié)。

        dubbo-container 容器模塊,是一個(gè) Standalone 的容器,以簡(jiǎn)單的 Main 加載 Spring 啟動(dòng),因?yàn)榉?wù)通常不需要 Tomcat/JBoss 等 Web 容器的特性,沒(méi)必要用 Web 容器去加載服務(wù)。

        主要模塊

        調(diào)用方式

        異步調(diào)用

        基于 NIO 的非阻塞實(shí)現(xiàn)并行調(diào)用,客戶(hù)端不需要啟動(dòng)多線程即可完成并行調(diào)用多個(gè)遠(yuǎn)程服務(wù),相對(duì)多線程開(kāi)銷(xiāo)較小

        異步調(diào)用

        本地調(diào)用

        使用了Injvm協(xié)議,是一個(gè)偽協(xié)議,它不開(kāi)啟端口,不發(fā)起遠(yuǎn)程調(diào)用,只在JVM內(nèi)直接關(guān)聯(lián),但執(zhí)行Dubbo的Filter鏈。

        Define injvm protocol:

        <dubbo:protocol name="injvm" /> 

        Set default protocol:

        <dubbo:provider protocol="injvm" />

        Set service protocol:

        <dubbo:service protocol="injvm" />

        Use injvm first:(服務(wù)暴露與服務(wù)引用都需要聲明injvm=“true”)

        <dubbo:consumer injvm="true" .../>
        <dubbo:provider injvm="true" .../>

        <dubbo:reference injvm="true" .../>   <dubbo:service injvm="true" .../>

        容錯(cuò)機(jī)制

        調(diào)用流程

        1、Cluster 將 Directory 中的多個(gè) Invoker 偽裝成一個(gè)Invoker,對(duì)上層透明,偽裝過(guò)程包含了容錯(cuò)邏輯

        2、Router 負(fù)責(zé)從多個(gè) Invoker 中按路由規(guī)則選出子集,比如讀寫(xiě)分離,應(yīng)用隔離等

        3、LoadBalance 負(fù)責(zé)從多個(gè) Invoker 中選出具體的一個(gè)用于本次調(diào)用,選的過(guò)程包含了負(fù)載均衡算法

        調(diào)用流程

        容錯(cuò)策略

        Dubbo 官網(wǎng)提出總共有六種容錯(cuò)策略

        1、Failover Cluster

        失敗自動(dòng)切換,當(dāng)出現(xiàn)失敗,重試其它服務(wù)器。(默認(rèn))

        2、Failfast Cluster

        快速失敗,只發(fā)起一次調(diào)用,失敗立即報(bào)錯(cuò)。通常用于非冪等性的寫(xiě)操作,比如新增記錄。

        3、Failsafe Cluster

        失敗安全,出現(xiàn)異常時(shí),直接忽略。通常用于寫(xiě)入審計(jì)日志等操作。

        4、Failback Cluster

        失敗自動(dòng)恢復(fù),后臺(tái)記錄失敗請(qǐng)求,定時(shí)重發(fā)。通常用于消息通知操作。

        5、Forking Cluster

        并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回。通常用于實(shí)時(shí)性要求較高的讀操作,但需要浪費(fèi)更多服務(wù)資源。
        可通過(guò) forks=”2”來(lái)設(shè)置最大并行數(shù)。

        6、Broadcast Cluster

        廣播調(diào)用所有提供者,逐個(gè)調(diào)用,任意一臺(tái)報(bào)錯(cuò)則報(bào)錯(cuò)。(2.1.0 開(kāi)始支持) 通常用于通知所有提供者更新緩存或日志等本地資源信息。

        總結(jié):在實(shí)際應(yīng)用中查詢(xún)語(yǔ)句容錯(cuò)策略建議使用默認(rèn) Failover Cluster,而增刪改建議使用 Failfast Cluster 或者使用 Failover Cluster(retries=”0”)策略,防止出現(xiàn)數(shù)據(jù)重復(fù)添加等等其它問(wèn)題!建議在設(shè)計(jì)接口時(shí)候把查詢(xún)接口方法單獨(dú)做一個(gè)接口提供查詢(xún)。

        連接方式

        Dubbo 的客戶(hù)端和服務(wù)端有三種連接方式,分別是:廣播、直連和使用Zookeeper注冊(cè)中心。

        Dubbo 廣播

        這種方式是dubbo官方入門(mén)程序所使用的連接方式,但是這種方式有很多問(wèn)題,在企業(yè)開(kāi)發(fā)中不使用廣播的方式。

        服務(wù)端配置:

        <!--配制dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-service"/>
        <!--使用multicast廣播注冊(cè)暴露服務(wù)地址-->
        <dubbo:registry address="multicast://192.168.9.4:88888" />

        <!--使用dubbo協(xié)議在20880端口暴露服務(wù)-->
        <dubbo:protocol name="dubbo" port="20880"/>

        <!--聲明暴露的服務(wù)接口-->
        <dubbo:service interface="com.demo.manger.service.TestService" ref="testServiceImpl" />

        客戶(hù)端配置:

        <!--配合dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-web"/>

        <!--使用multicast廣播注冊(cè)中心暴露服務(wù)地址 -->
        <dubbo:registry address="multicast://19.188.8.9:8888"/>

        <!--聲明需要暴露的接口-->
        <dubbo:reference interface="com.demo.manager.service.TestService" id="testService" timeout="1000000" />

        Dubbo 直連

        這種方式在企業(yè)中一般在開(kāi)發(fā)中環(huán)境中使用,但是生產(chǎn)環(huán)境很少使用,因?yàn)榉?wù)是直接調(diào)用,沒(méi)有使用注冊(cè)中心,很難對(duì)服務(wù)進(jìn)行管理。Dubbo 直連,首先要取消廣播,然后客戶(hù)端直接到指定需要的服務(wù)的 url 獲取服務(wù)即可。

        服務(wù)端配置:

        <!--配制dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-service"/>
        <!--使用multicast廣播注冊(cè)暴露服務(wù)地址-->
        <-- <dubbo:registry address="multicast://192.168.9.4:88888" /> -->
        <dubbo:registry adress="N/A">

        <!--使用dubbo協(xié)議在20880端口暴露服務(wù)-->
        <dubbo:protocol name="dubbo" port="20880"/>

        <!--聲明暴露的服務(wù)接口-->
        <dubbo:service interface="com.demo.manger.service.TestService" ref="testServiceImpl" />

        客戶(hù)端配置:

        <!--配合dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-web"/>

        <!--使用multicast廣播注冊(cè)中心暴露服務(wù)地址 -->
        <-- <dubbo:registry address="multicast://19.188.8.9:8888"/> -->

        <!--聲明需要暴露的接口-->
        <dubbo:reference interface="com.demo.manager.service.TestService" id="testService" timeout="1000000" url="dubbo://127.0.0.1:20880" />

        zookeeper 注冊(cè)中心

        Dubbo 注冊(cè)中心和廣播注冊(cè)中心配置類(lèi)似,不過(guò)需要指定注冊(cè)中心類(lèi)型和注冊(cè)中心地址,這個(gè)時(shí)候就不是把服務(wù)信息進(jìn)行廣播了,而是告訴給注冊(cè)中心進(jìn)行管理,這個(gè)時(shí)候我們就需要有一個(gè)注冊(cè)中心,官方推薦使用 zookeeper 作為注冊(cè)中心。

        Zookeeper 注冊(cè)中心

        注冊(cè)中心負(fù)責(zé)服務(wù)地址的注冊(cè)與查找,相當(dāng)于目錄服務(wù),服務(wù)提供者在啟動(dòng)時(shí)與注冊(cè)中心交互,消費(fèi)者不斷的發(fā)起請(qǐng)求獲取服務(wù)信息,注冊(cè)中心不轉(zhuǎn)發(fā)請(qǐng)求,壓力較小

        服務(wù)端配置:

        <!--配制dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-service"/>
        <!--使用multicast廣播注冊(cè)暴露服務(wù)地址-->
        <!-- <dubbo:registry address="multicast://192.168.9.4:88888" /> -->
        <!--<dubbo:registry adress="N/A"> -->
        <dubbo:registry protocol="zookeeper" address="192.168.37,136:2181">
        <!--使用dubbo協(xié)議在20880端口暴露服務(wù)-->
        <dubbo:protocol name="dubbo" port="20880"/>

        <!--聲明暴露的服務(wù)接口-->
        <dubbo:service interface="com.demo.manger.service.TestService" ref="testServiceImpl" />

        客戶(hù)端配置:

        <!--配合dubbo-->
        <!--提供應(yīng)用信息,用于計(jì)算依賴(lài)關(guān)系-->
        <dubbo:application name="demo-web"/>

        <!--使用multicast廣播注冊(cè)中心暴露服務(wù)地址 -->
        <-- <dubbo:registry address="multicast://19.188.8.9:8888"/> -->
        <dubbo:registry protocol="zookeeper" address="192.168.37.1336:2181"/>    

        <!--聲明需要暴露的接口-->
        <dubbo:reference interface="com.demo.manager.service.TestService" id="testService" timeout="1000000" />

        策略

        負(fù)載均衡策略

        1、Random LoadBalance,隨機(jī)(默認(rèn)的負(fù)載均衡策略)

        RandomLoadBalance 是加權(quán)隨機(jī)算法的具體實(shí)現(xiàn),可以完全隨機(jī),也可以按權(quán)重設(shè)置隨機(jī)概率。

        2、RoundRobin LoadBalance,輪循

        可以輪詢(xún)和加權(quán)輪詢(xún)。存在響應(yīng)慢的提供者會(huì)累積請(qǐng)求的問(wèn)題,比如:第二臺(tái)機(jī)器很慢,但沒(méi)掛,當(dāng)請(qǐng)求調(diào)到第二臺(tái)時(shí)就卡在那,久而久之,所有請(qǐng)求都卡在調(diào)到第二臺(tái)上。

        3、LeastActive LoadBalance,最少活躍調(diào)用數(shù)

        活躍調(diào)用數(shù)越小,表明該服務(wù)提供者效率越高,單位時(shí)間內(nèi)可處理更多的請(qǐng)求。此時(shí)應(yīng)優(yōu)先將請(qǐng)求分配給該服務(wù)提供者。

        4、ConsistentHash LoadBalance,一致性 Hash

        一致性 Hash 算法,相同參數(shù)的請(qǐng)求一定分發(fā)到一個(gè) provider 上去。provider 掛掉的時(shí)候,會(huì)基于虛擬節(jié)點(diǎn)均勻分配剩余的流量,抖動(dòng)不會(huì)太大。

        集群容錯(cuò)策略

        1、failover cluster(默認(rèn))

        失敗自動(dòng)切換,調(diào)用失敗時(shí),自動(dòng)重試其他機(jī)器。通常用于讀操作,但重試會(huì)帶來(lái)更長(zhǎng)延遲。

        2、Failfast Cluster
        快速失敗,只發(fā)起一次調(diào)用,失敗立即報(bào)錯(cuò)。通常用于非冪等性的寫(xiě)操作,比如新增記錄。

        3、Failsafe Cluster
        失敗安全,出現(xiàn)異常時(shí),直接忽略。通常用于寫(xiě)入審計(jì)日志等操作。

        4、Failback Cluster
        失敗自動(dòng)恢復(fù),后臺(tái)記錄失敗請(qǐng)求,定時(shí)重發(fā)。通常用于消息通知操作。

        5、Forking Cluster
        并行調(diào)用多個(gè)服務(wù)器,只要一個(gè)成功即返回。通常用于實(shí)時(shí)性要求較高的讀操作,但需要浪費(fèi)更多服務(wù)資源。

        動(dòng)態(tài)代理策略

        默認(rèn)使用 javassist 動(dòng)態(tài)字節(jié)碼生成,創(chuàng)建代理類(lèi)。也可以通過(guò) spi 擴(kuò)展機(jī)制配置自己的動(dòng)態(tài)代理策略。

        集群容錯(cuò)方案

        • 配置說(shuō)明,方案配置方式,優(yōu)先使用消費(fèi)端配置

        <!--服務(wù)端配置-->
        <dubbo:service cluster="failover"/>
        <!--消費(fèi)端配置-->
        <dubbo:reference cluster="failover"/>
        • 盡量在只在服務(wù)端進(jìn)行配置

        • cluster類(lèi)型均為小寫(xiě)

        • 默認(rèn)為FailoverCluster失敗切換方案

        集群容錯(cuò)方案support

        FailoverCluster(默認(rèn)):失敗切換

        • 場(chǎng)景:調(diào)用失敗后切換其他服務(wù)

        • 配置:

        <!--
        retries:重試次數(shù),不包括第一次,默認(rèn)2
        -->
        <dubbo:service cluster="failover" retries="3"/>
        • 代碼實(shí)現(xiàn)邏輯:

          1. 根據(jù)負(fù)載均衡策略選出需要調(diào)用的服務(wù)實(shí)例,排除已調(diào)用的

          2. 執(zhí)行選出的實(shí)例,并將其保存到已調(diào)用列表中

          3. 執(zhí)行實(shí)例成功即返回

          4. 執(zhí)行實(shí)例不成功,為到最大重試次數(shù)則執(zhí)行第一步,否則拋出RpcException異常

        FailbackCluster:失敗重試

        • 場(chǎng)景:調(diào)用失敗時(shí)記錄失敗請(qǐng)求,定時(shí)重發(fā)

        • 配置:

        <!--
        retries:重試次數(shù),不包括第一次,默認(rèn)3
        failbacktasks:定時(shí)器中最大掛起任務(wù)數(shù),默認(rèn)100
        -->
        <dubbo:service cluster="failback" retries="5" failbacktasks="200"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 根據(jù)負(fù)載均衡策略選出需要調(diào)用的服務(wù)實(shí)例

          2. 執(zhí)行選出的實(shí)例

          3. 執(zhí)行實(shí)例成功即返回

          4. 執(zhí)行異常則創(chuàng)建延時(shí)5秒的定時(shí)任務(wù),并加入時(shí)間輪定時(shí)器,第一次需要進(jìn)行定時(shí)器初始化,分為32個(gè)時(shí)間片,每1秒滾動(dòng)一次,最大掛起任務(wù)默認(rèn)100個(gè),超出最大任務(wù)數(shù)時(shí)拋出RejectedExecutionException異常。

          5. 重試執(zhí)行定時(shí)任務(wù),次數(shù)超出最大執(zhí)行次數(shù)停止,并輸出error日志,默認(rèn)為3次。

        FailfastCluster:快速失敗

        • 場(chǎng)景:調(diào)用失敗立即報(bào)錯(cuò)

        • 配置:

        <dubbo:service cluster="failfast"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 根據(jù)負(fù)載均衡策略選出需要調(diào)用的服務(wù)實(shí)例

          2. 執(zhí)行選出的實(shí)例

          3. 執(zhí)行實(shí)例成功即返回,失敗拋出RpcException異常

        FailsafeCluster:安全失敗

        • 場(chǎng)景:調(diào)用失敗后忽略

        • 配置:

        <dubbo:service cluster="failsafe"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 根據(jù)負(fù)載均衡策略選出需要調(diào)用的服務(wù)實(shí)例

          2. 執(zhí)行選出的實(shí)例

          3. 執(zhí)行實(shí)例成功即返回,失敗輸出error日志,并返RpcResult,視為忽略。

        ForkingCluster:并發(fā)處理

        • 場(chǎng)景:并發(fā)調(diào)用指定數(shù)量的服務(wù),一個(gè)成功則返回,對(duì)實(shí)時(shí)性要求高的場(chǎng)景,要求快速返回,需要使用更多服務(wù)器資源。

        • 配置:

        <!--
        forks:最大并發(fā)數(shù),默認(rèn)2
        timeout:并發(fā)返回超時(shí)時(shí)間,默認(rèn)1000ms
        -->
        <dubbo:service cluster="forking" forks="3" timeout="500"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 根據(jù)負(fù)載均衡策略選出幾個(gè)不同的服務(wù)實(shí)例

          2. 并發(fā)執(zhí)行選出的幾個(gè)實(shí)例,并將返回結(jié)果放入堵塞隊(duì)列中

          3. 返回堵塞隊(duì)列中的第一個(gè)值,如規(guī)定時(shí)間內(nèi)未獲取到隊(duì)列中的值或獲取到異常值則返回RPC異常。

        BroadcastCluster:廣播

        • 場(chǎng)景:廣播方式逐個(gè)調(diào)用服務(wù)提供者,有一個(gè)報(bào)錯(cuò)則返回錯(cuò)誤,多用于通知服務(wù)提供者更新本地資源信息,如緩存,日志等。

        • 配置:

        <dubbo:service cluster="broadcast"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 循環(huán)逐個(gè)執(zhí)行所有服務(wù)實(shí)例信息

          2. 保存一份返回結(jié)果和異常信息

          3. 執(zhí)行完全部實(shí)例后,如異常信息不為空,則拋出異常信息,否則返回最后一個(gè)實(shí)例的結(jié)果。

        AvailableCluster:可用服務(wù)

        • 場(chǎng)景:調(diào)用第一個(gè)可用服務(wù)

        • 配置:

        <dubbo:service cluster="available"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 循環(huán)所有服務(wù)實(shí)例信息

          2. 執(zhí)行第一個(gè)可用的實(shí)例,并返回結(jié)果

          3. 如無(wú)可用實(shí)例則返回RpcException異常

        MergeableCluster:合并處理

        • 場(chǎng)景:返回合并或疊加處理結(jié)果

        • 配置:

        <!--
        merger:合并發(fā)放名
        timeout:調(diào)用服務(wù)超時(shí)時(shí)間,默認(rèn)1000ms
        -->
        <dubbo:service cluster="mergeable" merger="true" timeout="500"/>
        • 代碼實(shí)現(xiàn)邏輯

          1. 判斷merger,為空、null、0、false、N/A是執(zhí)行第一個(gè)可用服務(wù)并返回結(jié)果,無(wú)可用則執(zhí)行第一個(gè)實(shí)例,并返回結(jié)果。

          2. 獲取方法實(shí)例的返回類(lèi)型

          3. 異步調(diào)用所有實(shí)例,并將異步結(jié)果Result存儲(chǔ)到結(jié)果集中,返回異常輸出error日志

          4. 結(jié)果集為空返回 RpcException,大小為 1時(shí)返回第一個(gè)Result

          5. 當(dāng)merger的第一個(gè)字符為“.”時(shí),判斷當(dāng) merger 實(shí)例返回類(lèi)型不為void,且返回類(lèi)型必須是結(jié)果集中第一個(gè)返回類(lèi)型的父類(lèi)型或相同類(lèi)型時(shí),循環(huán)執(zhí)行merger實(shí)例,每一次都傳入上一次的返回結(jié)果,最終返回獲取最后一次結(jié)果,非上述情況時(shí)循環(huán)執(zhí)行merger實(shí)例,返回結(jié)果集中的第一個(gè)結(jié)果。

          6. 當(dāng)merger為true或default時(shí)使用Dubbo默認(rèn)合并器,否則使用自定義merger合并器,合并后返回

        RegistryAwareCluster:默認(rèn)標(biāo)識(shí)、注冊(cè)標(biāo)識(shí)

        • 場(chǎng)景:調(diào)用注冊(cè)默認(rèn)標(biāo)識(shí)的服務(wù)

        • 配置:

        <!--
        default:默認(rèn)標(biāo)識(shí)
        -->
        <dubbo:registry address="zookeeper://xxx..." default="true"/>
        <dubbo:service cluster="registryaware"/>
        • 代碼實(shí)現(xiàn)邏輯

          1.8 循環(huán)所有服務(wù)實(shí)例信息

          2. 執(zhí)行第一個(gè)可用的實(shí)例且default為true的實(shí)例

          3. 無(wú)默認(rèn)實(shí)例則執(zhí)行第一個(gè)可用的實(shí)例

          4. 無(wú)可用的實(shí)例則拋出RpcException異常

        主要配置

        配置應(yīng)用信息:

        <dubbo:application name=“appName-provider” />

        配置注冊(cè)中心相關(guān)信息:

        <dubbo:registryid=“zk” protocol=“zookeeper” address=“127.0.0.1:2181” />

        配置服務(wù)協(xié)議:

        <dubbo:protocol name=“dubbo” port=“20880” threadpool=“cached” threads=“80” />

        配置所有暴露服務(wù)缺省值:

        <dubbo:provider registry=“zk” protocol=“dubbo” retries=“0” version=“1.0.0” timeout=“3000” threadpool=“cached” threads=“4”/>

        配置暴露服務(wù):

        <dubbo:service interface=“com.orgname.app.serviceX” ref=“serviceX” />

        配置所有引用服務(wù)缺省值:

        <dubbo:consumer check=“false” timeout=“1000” version=“1.0” retries=“0” async=“false” />

        注解配置:

        com.alibaba.dubbo.config.annotation.Service 配置暴露服務(wù)

        com.alibaba.dubbo.config.annotation.Reference配置引用服務(wù)

        超時(shí)設(shè)置

        Dubbo消費(fèi)端

        全局超時(shí)配置

        <dubbo:consumer timeout="5000" />

        指定接口以及特定方法超時(shí)配置

        <dubbo:reference interface="com.foo.BarService" timeout="2000">
            <dubbo:method name="sayHello" timeout="3000" />
        </dubbo:reference>

        Dubbo服務(wù)端

        全局超時(shí)配置

        <dubbo:provider timeout="5000" />

        指定接口以及特定方法超時(shí)配置

        <dubbo:provider interface="com.foo.BarService" timeout="2000">
            <dubbo:method name="sayHello" timeout="3000" />
        </dubbo:provider>

        支持協(xié)議

        1、Dubbo 協(xié)議(官方推薦協(xié)議)

        優(yōu)點(diǎn):采用NIO復(fù)用單一長(zhǎng)連接,并使用線程池并發(fā)處理請(qǐng)求,減少握手和加大并發(fā)效率,性能較好(推薦使用)

        缺點(diǎn):大文件上傳時(shí),可能出現(xiàn)問(wèn)題(不使用 Dubbo 文件上傳)

        2、RMI(Remote Method Invocation)協(xié)議

        優(yōu)點(diǎn):JDK 自帶的能力。可與原生 RMI 互操作,基于 TCP 協(xié)議

        缺點(diǎn):偶爾連接失敗.

        3、Hessian協(xié)議

        優(yōu)點(diǎn):可與原生 Hessian 互操作,基于 HTTP 協(xié)議

        缺點(diǎn):需 hessian.jar 支持,http 短連接的*開(kāi)銷(xiāo)大8

        常用設(shè)計(jì)模式

        Dubbo 框架在初始化和通信過(guò)程中使用了多種設(shè)計(jì)模式,可靈活控制類(lèi)加載、權(quán)限控制等功能。

        工廠模式

        Provider 在 export 服務(wù)時(shí),會(huì)調(diào)用 ServiceConfig 的 export 方法。ServiceConfig 中有個(gè)字段:

        private static final Protocol protocol =
        ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

        Dubbo 里有很多這種代碼。這也是一種工廠模式,只是實(shí)現(xiàn)類(lèi)的獲取采用了 JDK SPI 的機(jī)制。這么實(shí)現(xiàn)的優(yōu)點(diǎn)是可擴(kuò)展性強(qiáng),想要擴(kuò)展實(shí)現(xiàn),只需要在 classpath下增加個(gè)文件就可以了,代碼零侵入。另外,像上面的 Adaptive 實(shí)現(xiàn),可以做到調(diào)用時(shí)動(dòng)態(tài)決定調(diào)用哪個(gè)實(shí)現(xiàn),但是由于這種實(shí)現(xiàn)采用了動(dòng)態(tài)代理,會(huì)造成代碼調(diào)試比較麻煩,需要分析出實(shí)際調(diào)用的實(shí)現(xiàn)類(lèi)。

        裝飾器模式

        Dubbo 在啟動(dòng)和調(diào)用階段都大量使用了裝飾器模式。以 Provider 提供的調(diào)用鏈為例,具體的調(diào)用鏈代碼是在 ProtocolFilterWrapper 的buildInvokerChain 完成的,具體是將注解中含有 group=provider 的 Filter 實(shí)現(xiàn),按照 order 排序,最后的調(diào)用順序是:

        EchoFilter -> ClassLoaderFilter -> GenericFilter -> ContextFilter ->
        ExecuteLimitFilter -> TraceFilter -> TimeoutFilter -> MonitorFilter ->
        ExceptionFilter

        更確切地說(shuō),這里是裝飾器和責(zé)任鏈模式的混合使用。例如,EchoFilter 的作用是判斷是否是回聲測(cè)試請(qǐng)求,是的話直接返回內(nèi)容,這是一種責(zé)任鏈的體現(xiàn)。而像ClassLoaderFilter 則只是在主功能上添加了功能,更改當(dāng)前線程的 ClassLoader,這是典型的裝飾器模式。

        觀察者模式

        Dubbo 的 Provider 啟動(dòng)時(shí),需要與注冊(cè)中心交互,先注冊(cè)自己的服務(wù),再訂閱自己的服務(wù),訂閱時(shí),采用了觀察者模式,開(kāi)啟一個(gè) listener。注冊(cè)中心會(huì)每 5 秒定時(shí)檢查是否有服務(wù)更新,如果有更新,向該服務(wù)的提供者發(fā)送一個(gè) notify 消息,provider 接受到 notify 消息后,即運(yùn)行 NotifyListener 的 notify 方法,執(zhí)行監(jiān)聽(tīng)器方法。

        動(dòng)態(tài)代理模式

        Dubbo 擴(kuò)展 JDK SPI 的類(lèi) ExtensionLoader 的 Adaptive 實(shí)現(xiàn)是典型的動(dòng)態(tài)代理實(shí)現(xiàn)。Dubbo 需要靈活地控制實(shí)現(xiàn)類(lèi),即在調(diào)用階段動(dòng)態(tài)地根據(jù)參數(shù)決定調(diào)用哪個(gè)實(shí)現(xiàn)類(lèi),所以采用先生成代理類(lèi)的方法,能夠做到靈活的調(diào)用。生成代理類(lèi)的代碼是 ExtensionLoader 的 createAdaptiveExtensionClassCode 方法。代理類(lèi)的主要邏輯是,獲取 URL 參數(shù)中指定參數(shù)的值作為獲取實(shí)現(xiàn)類(lèi)的 key

        工作流程

        整體流程:

        第一步:provider 向注冊(cè)中心去注冊(cè)

        第二步:consumer 從注冊(cè)中心訂閱服務(wù),注冊(cè)中心會(huì)通知 consumer 注冊(cè)好的服務(wù)

        第三步:consumer 調(diào)用 provider

        第四步:consumer 和 provider 都異步通知監(jiān)控中心

        流程圖

        總結(jié)

        最后用一張圖來(lái)形象的模擬 Dubbo 的使用:

        使用

        以上只是我總結(jié)的一些關(guān)于 dubbo 最基礎(chǔ)的原理及使用介紹,至于代碼編寫(xiě)過(guò)程的 bug 處理經(jīng)驗(yàn),環(huán)境搭建、項(xiàng)目布局等等問(wèn)題,需要我們?cè)谄綍r(shí)開(kāi)發(fā)中,將系統(tǒng)知識(shí)與實(shí)戰(zhàn)經(jīng)驗(yàn)相結(jié)合去總結(jié),這樣才能真正的去掌握這項(xiàng)技術(shù)點(diǎn)。

        Dubbo 目前是我用到過(guò)的最多的分布式框架,寫(xiě)出來(lái)的內(nèi)容也是最多的,不過(guò)由于Dubbo用的太多,而 SpringCloud 難度比 Dubbo 要小很多,現(xiàn)在大部分項(xiàng)目都即將開(kāi)始轉(zhuǎn)投到了 SpringCloud 上面,后面也會(huì)出更多的 SpringCloud 相關(guān)的文章。

        關(guān)于我

        下面的是我的個(gè)人二維碼圖片,希望能跟大家一起進(jìn)階,共同進(jìn)步。


        個(gè)人二維碼

        小羽也建立了一個(gè)技術(shù)群,如果你想了解到更多關(guān)于IT行業(yè)的技術(shù)以及生活中遇到的問(wèn)題,歡迎小伙伴進(jìn)群交流,只需添加我好友,備注:進(jìn)群即可,期待你們的加入。

        點(diǎn)擊公眾號(hào),星標(biāo)置頂,小羽的每一次分享都不會(huì)錯(cuò)過(guò)!

        推薦閱讀

        再深一點(diǎn):如何給女朋友解釋什么是微服務(wù)?
        別小看 Log 日志,它難住了我們組的架構(gòu)師
        圖文詳解:阿里寵兒【小兔】RabbitMQ的養(yǎng)成攻略
        周末給女友講了遍加密算法,沒(méi)想到…

        瀏覽 64
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(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>
            国产成人91一区二区三区APP | 青青久操美女b | 大鸡吧视频 | 亚欧精品视频一区二区三区 | 激情五月天av | 精品午夜久久久 | 黄色一级欧美视频 | 做爰过程很黄口述 | 色99网站 | 毛茸茸的孕妇孕交XXXX |