日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

微服务面试必问的Dubbo,这么详细还怕自己找不到工作?

發(fā)布時(shí)間:2025/3/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微服务面试必问的Dubbo,这么详细还怕自己找不到工作? 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Dubbo 起源于阿里巴巴,對(duì)于我們做電商開發(fā)的人來說,基本是首選的技術(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)已無法應(yīng)對(duì)。

服務(wù)化的進(jìn)一步發(fā)展,服務(wù)越來越多,服務(wù)之間的調(diào)用和依賴關(guān)系也越來越復(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í)的開源 RPC 框架、提供服務(wù)自動(dòng)注冊(cè)、自動(dòng)發(fā)現(xiàn)等高效治理方案,可以和 Spring 框架無縫集成

簡(jiǎn)單的說,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 全稱為 remote procedure call,即遠(yuǎn)程過程調(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)用,所以需要通過網(wǎng)絡(luò)來表達(dá)調(diào)用的語義和傳達(dá)調(diào)用的數(shù)據(jù)

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

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

原理

服務(wù)消費(fèi)方(client)調(diào)用以本地調(diào)用方式調(diào)用服務(wù)。客戶端存根(client stub)接收到調(diào)用后負(fù)責(zé)將方法、參數(shù)等編碼成能在網(wǎng)絡(luò)中傳輸?shù)南Ⅲw。然后,客戶端存根找到服務(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ù)化,提高開發(fā)效率,調(diào)優(yōu)性能,節(jié)省競(jìng)爭(zhēng)資源

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

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

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

核心功能

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

Cluster:服務(wù)框架,提供基于接口方法的透明遠(yuǎn)程過程調(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)者列表擇其一發(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ù)提供者無狀態(tài),任意一臺(tái)宕掉后,不影響使用

流程

?

?

服務(wù)治理

治理原因

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

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

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

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

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

主要特性

透明遠(yuǎn)程調(diào)用:就像調(diào)用本地方法一樣調(diào)用遠(yuǎn)程方法;只需簡(jiǎn)單配置,沒有任何 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è)中心基于接口名查詢服務(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í),訪問控制,權(quán)重調(diào)整,負(fù)載均衡,等手動(dòng)配置

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

服務(wù)治理

?

?

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

整體架構(gòu)

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

圖例說明:

整體架構(gòu)

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

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

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

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

各層說明

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

proxy 服務(wù)代理層:服務(wù)接口透明代理,生成服務(wù)的客戶端 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 類和通用模型

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 ,用戶通過 Config 使用 Dubbo ,隱藏 Dubbo 所有細(xì)節(jié)。

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

主要模塊

?

?

調(diào)用方式

異步調(diào)用

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

異步調(diào)用

本地調(diào)用

使用了Injvm協(xié)議,是一個(gè)偽協(xié)議,它不開啟端口,不發(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ì)上層透明,偽裝過程包含了容錯(cuò)邏輯

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

3、LoadBalance 負(fù)責(zé)從多個(gè) Invoker 中選出具體的一個(gè)用于本次調(diào)用,選的過程包含了負(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ò)。通常用于非冪等性的寫操作,比如新增記錄。

3、Failsafe Cluster

失敗安全,出現(xiàn)異常時(shí),直接忽略。通常用于寫入審計(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ù)資源。
可通過 forks=”2”來設(shè)置最大并行數(shù)。

6、Broadcast Cluster

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

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

連接方式

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

Dubbo 廣播

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

服務(wù)端配置:

<!--配制dubbo--> <!--提供應(yīng)用信息,用于計(jì)算依賴關(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"?/>

客戶端配置:

<!--配合dubbo--> <!--提供應(yīng)用信息,用于計(jì)算依賴關(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è)中一般在開發(fā)中環(huán)境中使用,但是生產(chǎn)環(huán)境很少使用,因?yàn)榉?wù)是直接調(diào)用,沒有使用注冊(cè)中心,很難對(duì)服務(wù)進(jìn)行管理。Dubbo 直連,首先要取消廣播,然后客戶端直接到指定需要的服務(wù)的 url 獲取服務(wù)即可。

服務(wù)端配置:

<!--配制dubbo--> <!--提供應(yīng)用信息,用于計(jì)算依賴關(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"?/>

客戶端配置:

<!--配合dubbo--> <!--提供應(yīng)用信息,用于計(jì)算依賴關(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è)中心配置類似,不過需要指定注冊(cè)中心類型和注冊(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ì)算依賴關(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"?/>

客戶端配置:

<!--配合dubbo--> <!--提供應(yīng)用信息,用于計(jì)算依賴關(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,輪循

可以輪詢和加權(quán)輪詢。存在響應(yīng)慢的提供者會(huì)累積請(qǐng)求的問題,比如:第二臺(tái)機(jī)器很慢,但沒掛,當(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ì)帶來更長(zhǎng)延遲。

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

3、Failsafe Cluster
失敗安全,出現(xiàn)異常時(shí),直接忽略。通常用于寫入審計(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)建代理類。也可以通過 spi 擴(kuò)展機(jī)制配置自己的動(dòng)態(tài)代理策略。

集群容錯(cuò)方案

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

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

  • cluster類型均為小寫

  • 默認(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. 如無可用實(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é)果,無可用則執(zhí)行第一個(gè)實(shí)例,并返回結(jié)果。

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

    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í)例返回類型不為void,且返回類型必須是結(jié)果集中第一個(gè)返回類型的父類型或相同類型時(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. 無默認(rèn)實(shí)例則執(zhí)行第一個(gè)可用的實(shí)例

    4. 無可用的實(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)問題(不使用 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 短連接的*開銷大8

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

Dubbo 框架在初始化和通信過程中使用了多種設(shè)計(jì)模式,可靈活控制類加載、權(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)類的獲取采用了 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)類。

裝飾器模式

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

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

觀察者模式

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

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

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

工作流程

整體流程:

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

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

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

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

流程圖

?

?

總結(jié)

最后用一張圖來形象的模擬 Dubbo 的使用:

使用

有道無術(shù),術(shù)可成;有術(shù)無道,止于術(shù)

歡迎大家關(guān)注Java之道公眾號(hào)

好文章,我在看??

總結(jié)

以上是生活随笔為你收集整理的微服务面试必问的Dubbo,这么详细还怕自己找不到工作?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。