Dubbo面試題(2021最新版)

基礎知識

為什么要用 Dubbo振乏?

隨著服務化的進一步發(fā)展瞻坝,服務越來越多暮蹂,服務之間的調(diào)用和依賴關系也越來越復雜怨愤,誕生了面向服務的架構(gòu)體系(SOA)派敷,也因此衍生出了一系列相應的技術(shù),如對服務提供、服務調(diào)用篮愉、連接處理般眉、通信協(xié)議、序列化方式潜支、服務發(fā)現(xiàn)、服務路由柿汛、日志輸出等行為進行封裝的服務框架冗酿。就這樣為分布式系統(tǒng)的服務治理框架就出現(xiàn)了,Dubbo 也就這樣產(chǎn)生了络断。

Dubbo 是什么裁替?

Dubbo 是一款高性能、輕量級的開源 RPC 框架貌笨,提供服務自動注冊弱判、自動發(fā)現(xiàn)等高效服務治理方案, 可以和 Spring 框架無縫集成锥惋。

Dubbo 的使用場景有哪些昌腰?

  • 透明化的遠程方法調(diào)用:就像調(diào)用本地方法一樣調(diào)用遠程方法,只需簡單配置膀跌,沒有任何API侵入遭商。
  • 軟負載均衡及容錯機制:可在內(nèi)網(wǎng)替代 F5 等硬件負載均衡器,降低成本捅伤,減少單點劫流。
  • 服務自動注冊與發(fā)現(xiàn):不再需要寫死服務提供方地址,注冊中心基于接口名查詢服務提供者的IP地址丛忆,并且能夠平滑添加或刪除服務提供者祠汇。

Dubbo 核心功能有哪些?

  • Remoting:網(wǎng)絡通信框架熄诡,提供對多種NIO框架抽象封裝可很,包括“同步轉(zhuǎn)異步”和“請求-響應”模式的信息交換方式。
  • Cluster:服務框架粮彤,提供基于接口方法的透明遠程過程調(diào)用根穷,包括多協(xié)議支持,以及軟負載均衡导坟,失敗容錯屿良,地址路由,動態(tài)配置等集群支持惫周。
  • Registry:服務注冊尘惧,基于注冊中心目錄服務,使服務消費方能動態(tài)的查找服務提供方递递,使地址透明喷橙,使服務提供方可以平滑增加或減少機器啥么。

架構(gòu)設計

Dubbo 核心組件有哪些?

  • Provider:暴露服務的服務提供方
  • Consumer:調(diào)用遠程服務消費方
  • Registry:服務注冊與發(fā)現(xiàn)注冊中心
  • Monitor:監(jiān)控中心和訪問調(diào)用統(tǒng)計
  • Container:服務運行容器

Dubbo 服務器注冊與發(fā)現(xiàn)的流程贰逾?

服務容器Container負責啟動悬荣,加載,運行服務提供者疙剑。

服務提供者Provider在啟動時氯迂,向注冊中心注冊自己提供的服務。

服務消費者Consumer在啟動時言缤,向注冊中心訂閱自己所需的服務嚼蚀。

注冊中心Registry返回服務提供者地址列表給消費者,如果有變更管挟,注冊中心將基于長連接推送變更數(shù)據(jù)給消費者轿曙。

服務消費者Consumer,從提供者地址列表中僻孝,基于軟負載均衡算法导帝,選一臺提供者進行調(diào)用,如果調(diào)用失敗穿铆,再選另一臺調(diào)用舟扎。

服務消費者Consumer和提供者Provider,在內(nèi)存中累計調(diào)用次數(shù)和調(diào)用時間悴务,定時每分鐘發(fā)送一次統(tǒng)計數(shù)據(jù)到監(jiān)控中心Monitor睹限。

Dubbo 的整體架構(gòu)設計有哪些分層?

接口服務層(Service):該層與業(yè)務邏輯相關,根據(jù) provider 和 consumer 的業(yè)務設計對應的接口和實現(xiàn)

配置層(Config):對外配置接口讯檐,以 ServiceConfig 和 ReferenceConfig 為中心

服務代理層(Proxy):服務接口透明代理羡疗,生成服務的客戶端 Stub 和 服務端的 Skeleton,以 ServiceProxy 為中心别洪,擴展接口為 ProxyFactory

服務注冊層(Registry):封裝服務地址的注冊和發(fā)現(xiàn)叨恨,以服務 URL 為中心,擴展接口為 RegistryFactory挖垛、Registry痒钝、RegistryService

路由層(Cluster):封裝多個提供者的路由和負載均衡,并橋接注冊中心痢毒,以Invoker 為中心送矩,擴展接口為 Cluster、Directory哪替、Router 和 LoadBlancce

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

遠程調(diào)用層(Protocal):封裝 RPC 調(diào)用晌块,以 Invocation 和 Result 為中心爱沟,擴展接口為 Protocal、Invoker 和 Exporter

信息交換層(Exchange):封裝請求響應模式匆背,同步轉(zhuǎn)異步呼伸。以 Request 和Response 為中心,擴展接口為 Exchanger钝尸、ExchangeChannel蜂大、ExchangeClient 和 ExchangeServer

網(wǎng)絡 傳輸 層(Transport):抽象 mina 和 netty 為統(tǒng)一接口,以 Message 為中心蝶怔,擴展接口為 Channel、Transporter兄墅、Client踢星、Server 和 Codec

數(shù)據(jù)序列化層(Serialize):可復用的一些工具,擴展接口為 Serialization隙咸、ObjectInput沐悦、ObjectOutput 和 ThreadPool

Dubbo Monitor 實現(xiàn)原理?

Consumer 端在發(fā)起調(diào)用之前會先走 filter 鏈五督;provider 端在接收到請求時也是先走 filter 鏈藏否,然后才進行真正的業(yè)務邏輯處理。默認情況下充包,在 consumer 和 provider 的 filter 鏈中都會有 Monitorfilter副签。

1、MonitorFilter 向 DubboMonitor 發(fā)送數(shù)據(jù)

2基矮、DubboMonitor 將數(shù)據(jù)進行聚合后(默認聚合 1min 中的統(tǒng)計數(shù)據(jù))暫存到ConcurrentMap<Statistics, AtomicReference> statisticsMap淆储,然后使用一個含有 3 個線程(線程名字:DubboMonitorSendTimer)的線程池每隔 1min 鐘,調(diào)用 SimpleMonitorService 遍歷發(fā)送 statisticsMap 中的統(tǒng)計數(shù)據(jù)家浇,每發(fā)送完畢一個本砰,就重置當前的 Statistics 的 AtomicReference

3、SimpleMonitorService 將這些聚合數(shù)據(jù)塞入 BlockingQueue queue 中(隊列大寫為 100000)

4钢悲、SimpleMonitorService 使用一個后臺線程(線程名為:DubboMonitorAsyncWriteLogThread)將 queue 中的數(shù)據(jù)寫入文件(該線程以死循環(huán)的形式來寫)

5点额、SimpleMonitorService 還會使用一個含有 1 個線程(線程名字:DubboMonitorTimer)的線程池每隔 5min 鐘,將文件中的統(tǒng)計數(shù)據(jù)畫成圖表

分布式框架

Dubbo 類似的分布式框架還有哪些莺琳?

比較著名的就是 Spring Cloud还棱。

Dubbo 和 Spring Cloud 有什么關系?

Dubbo 是 SOA 時代的產(chǎn)物惭等,它的關注點主要在于服務的調(diào)用诱贿,流量分發(fā)、流量監(jiān)控和熔斷。而 Spring Cloud 誕生于微服務架構(gòu)時代珠十,考慮的是微服務治理的方方面面料扰,另外由于依托了 Spring、Spring Boot 的優(yōu)勢之上焙蹭,兩個框架在開始目標就不一致晒杈,Dubbo 定位服務治理、Spring Cloud 是打造一個生態(tài)孔厉。

Dubbo 和 Spring Cloud 有什么哪些區(qū)別拯钻?

Dubbo 底層是使用 Netty 這樣的 NIO 框架,是基于 TCP 協(xié)議傳輸?shù)淖颍浜弦?Hession 序列化完成 RPC 通信粪般。

Spring Cloud 是基于 Http 協(xié)議 Rest 接口調(diào)用遠程過程的通信,相對來說 Http 請求會有更大的報文污桦,占的帶寬也會更多亩歹。但是 REST 相比 RPC 更為靈活,服務提供方和調(diào)用方的依賴只依靠一紙契約凡橱,不存在代碼級別的強依賴小作,這在強調(diào)快速演化的微服務環(huán)境下,顯得更為合適稼钩,至于注重通信速度還是方便靈活性顾稀,具體情況具體考慮。

Dubbo 和 Dubbox 之間的區(qū)別坝撑?

Dubbox 是繼 Dubbo 停止維護后静秆,當當網(wǎng)基于 Dubbo 做的一個擴展項目,如加了服務可 Restful 調(diào)用巡李,更新了開源組件等诡宗。

注冊中心

Dubbo 有哪些注冊中心?

  • Multicast 注冊中心:Multicast 注冊中心不需要任何中心節(jié)點击儡,只要廣播地址塔沃,就能進行服務注冊和發(fā)現(xiàn),基于網(wǎng)絡中組播傳輸實現(xiàn)。
  • Zookeeper 注冊中心:基于分布式協(xié)調(diào)系統(tǒng) Zookeeper 實現(xiàn)阳谍,采用 Zookeeper 的 watch 機制實現(xiàn)數(shù)據(jù)變更蛀柴。
  • Redis 注冊中心:基于 Redis 實現(xiàn),采用 key/map 存儲矫夯,key 存儲服務名和類型鸽疾,map 中 key 存儲服務 url,value 服務過期時間训貌≈瓢梗基于 Redis 的發(fā)布/訂閱模式通知數(shù)據(jù)變更冒窍。
  • Simple 注冊中心。

推薦使用 Zookeeper 作為注冊中心

Dubbo 的注冊中心集群掛掉豺鼻,發(fā)布者和訂閱者之間還能通信么转晰?

可以通訊噩斟。啟動 Dubbo 時挫以,消費者會從 Zookeeper 拉取注冊的生產(chǎn)者的地址接口等數(shù)據(jù)诫惭,緩存在本地。每次調(diào)用時桩了,按照本地存儲的地址進行調(diào)用附帽。

集群

Dubbo集群提供了哪些負載均衡策略?

  • Random LoadBalance: 隨機選取提供者策略井誉,有利于動態(tài)調(diào)整提供者權(quán)重蕉扮。截面碰撞率高,調(diào)用次數(shù)越多颗圣,分布越均勻喳钟。
  • RoundRobin LoadBalance: 輪循選取提供者策略,平均分布欠啤,但是存在請求累積的問題。
  • LeastActive LoadBalance: 最少活躍調(diào)用策略屋灌,解決慢提供者接收更少的請求洁段。
  • ConstantHash LoadBalance: 一致性 Hash 策略,使相同參數(shù)請求總是發(fā)到同一提供者共郭,一臺機器宕機祠丝,可以基于虛擬節(jié)點,分攤至其他提供者除嘹,避免引起提供者的劇烈變動写半。

默認為 Random 隨機調(diào)用。

Dubbo的集群容錯方案有哪些尉咕?

  • Failover Cluster:失敗自動切換叠蝇,當出現(xiàn)失敗,重試其它服務器年缎。通常用于讀操作悔捶,但重試會帶來更長延遲。
  • Failfast Cluster:快速失敗单芜,只發(fā)起一次調(diào)用蜕该,失敗立即報錯。通常用于非冪等性的寫操作洲鸠,比如新增記錄堂淡。
  • Failsafe Cluster:失敗安全馋缅,出現(xiàn)異常時,直接忽略绢淀。通常用于寫入審計日志等操作萤悴。
  • Failback Cluster:失敗自動恢復,后臺記錄失敗請求更啄,定時重發(fā)稚疹。通常用于消息通知操作。
  • Forking Cluster:并行調(diào)用多個服務器祭务,只要一個成功即返回内狗。通常用于實時性要求較高的讀操作,但需要浪費更多服務資源义锥×常可通過 forks=”2″ 來設置最大并行數(shù)。
  • Broadcast Cluster:廣播調(diào)用所有提供者拌倍,逐個調(diào)用赂鲤,任意一臺報錯則報錯 。通常用于通知所有提供者更新緩存或日志等本地資源信息柱恤。

默認的容錯方案是 Failover Cluster数初。

配置

Dubbo 配置文件是如何加載到 Spring 中的?

Spring 容器在啟動的時候梗顺,會讀取到 Spring 默認的一些 schema 以及 Dubbo 自定義的 schema泡孩,每個 schema 都會對應一個自己的 NamespaceHandler,NamespaceHandler 里面通過 BeanDefinitionParser 來解析配置信息并轉(zhuǎn)化為需要加載的 bean 對象寺谤!

說說核心的配置有哪些仑鸥?

標簽 用途 解釋
<dubbo:service/> 服務配置 用于暴露一個服務,定義服務的元信息变屁,一個服務可以用多個協(xié)議暴露眼俊,一個服務也可以注冊到多個注冊中心
<dubbo:reference/> 引用配置 用于創(chuàng)建一個遠程服務代理,一個引用可以指向多個注冊中心
<dubbo:protocol/> 協(xié)議配置 用于配置提供服務的協(xié)議信息粟关,協(xié)議由提供方指定疮胖,消費方被動接受
<dubbo:application/> 應用配置 用于配置當前應用信息,不管該應用是提供者還是消費者
<dubbo:module/> 模塊配置 用于配置當前模塊信息闷板,可選
<dubbo:registry/> 注冊中心配置 用于配置連接注冊中心相關信息
<dubbo:monitor/> 監(jiān)控中心配置 用于配置連接監(jiān)控中心相關信息获列,可選
<dubbo:provider/> 提供方配置 當 ProtocolConfig 和 ServiceConfig 某屬性沒有配置時,采用此缺省值蛔垢,可選
<dubbo:consumer/> 消費方配置 當 ReferenceConfig 某屬性沒有配置時击孩,采用此缺省值,可選
<dubbo:method/> 方法配置 用于 ServiceConfig 和 ReferenceConfig 指定方法級的配置信息
<dubbo:argument/> 參數(shù)配置 用于指定方法參數(shù)配置

Dubbo 超時設置有哪些方式鹏漆?

Dubbo 超時設置有兩種方式:

  • 服務提供者端設置超時時間巩梢,在Dubbo的用戶文檔中创泄,推薦如果能在服務端多配置就盡量多配置,因為服務提供者比消費者更清楚自己提供的服務特性括蝠。
  • 服務消費者端設置超時時間鞠抑,如果在消費者端設置了超時時間,以消費者端為主忌警,即優(yōu)先級更高搁拙。因為服務調(diào)用方設置超時時間控制性更靈活。如果消費方超時法绵,服務端線程不會定制箕速,會產(chǎn)生警告。

服務調(diào)用超時會怎么樣朋譬?

dubbo 在調(diào)用服務不成功時盐茎,默認是會重試兩次。

通信協(xié)議

Dubbo 使用的是什么通信框架?

默認使用 Netty 作為通訊框架徙赢。

Dubbo 支持哪些協(xié)議字柠,它們的優(yōu)缺點有哪些?

  • Dubbo: 單一長連接和 NIO 異步通訊狡赐,適合大并發(fā)小數(shù)據(jù)量的服務調(diào)用窑业,以及消費者遠大于提供者。傳輸協(xié)議 TCP枕屉,異步 Hessian 序列化常柄。Dubbo推薦使用dubbo協(xié)議
  • RMI: 采用 JDK 標準的 RMI 協(xié)議實現(xiàn)搀庶,傳輸參數(shù)和返回參數(shù)對象需要實現(xiàn) Serializable 接口拐纱,使用 Java 標準序列化機制铜异,使用阻塞式短連接哥倔,傳輸數(shù)據(jù)包大小混合,消費者和提供者個數(shù)差不多揍庄,可傳文件咆蒿,傳輸協(xié)議 TCP。 多個短連接 TCP 協(xié)議傳輸蚂子,同步傳輸沃测,適用常規(guī)的遠程服務調(diào)用和 RMI 互操作。在依賴低版本的 Common-Collections 包食茎,Java 序列化存在安全漏洞蒂破。
  • WebService:基于 WebService 的遠程調(diào)用協(xié)議,集成 CXF 實現(xiàn)别渔,提供和原生 WebService 的互操作附迷。多個短連接惧互,基于 HTTP 傳輸,同步傳輸喇伯,適用系統(tǒng)集成和跨語言調(diào)用喊儡。
  • HTTP: 基于 Http 表單提交的遠程調(diào)用協(xié)議,使用 Spring 的 HttpInvoke 實現(xiàn)稻据。多個短連接艾猜,傳輸協(xié)議 HTTP,傳入?yún)?shù)大小混合捻悯,提供者個數(shù)多于消費者匆赃,需要給應用程序和瀏覽器 JS 調(diào)用。
  • Hessian:集成 Hessian 服務秋度,基于 HTTP 通訊炸庞,采用 Servlet 暴露服務,Dubbo 內(nèi)嵌 Jetty 作為服務器時默認實現(xiàn)荚斯,提供與 Hession 服務互操作埠居。多個短連接,同步 HTTP 傳輸事期,Hessian 序列化滥壕,傳入?yún)?shù)較大,提供者大于消費者兽泣,提供者壓力較大绎橘,可傳文件。
  • Memcache:基于 Memcache實現(xiàn)的 RPC 協(xié)議唠倦。
  • Redis:基于 Redis 實現(xiàn)的RPC協(xié)議称鳞。

設計模式

Dubbo 用到哪些設計模式?

Dubbo 框架在初始化和通信過程中使用了多種設計模式稠鼻,可靈活控制類加載冈止、權(quán)限控制等功能。

工廠模式

Provider 在 export 服務時候齿,會調(diào)用 ServiceConfig 的 export 方法熙暴。ServiceConfig中有個字段:

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

Dubbo 里有很多這種代碼。這也是一種工廠模式慌盯,只是實現(xiàn)類的獲取采用了 JDKSPI 的機制周霉。這么實現(xiàn)的優(yōu)點是可擴展性強,想要擴展實現(xiàn)亚皂,只需要在 classpath下增加個文件就可以了俱箱,代碼零侵入。另外灭必,像上面的 Adaptive 實現(xiàn)狞谱,可以做到調(diào)用時動態(tài)決定調(diào)用哪個實現(xiàn)巍膘,但是由于這種實現(xiàn)采用了動態(tài)代理,會造成代碼調(diào)試比較麻煩芋簿,需要分析出實際調(diào)用的實現(xiàn)類峡懈。

裝飾器模式

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

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

更確切地說磷支,這里是裝飾器和責任鏈模式的混合使用。例如食寡,EchoFilter 的作用是判斷是否是回聲測試請求雾狈,是的話直接返回內(nèi)容,這是一種責任鏈的體現(xiàn)抵皱。而像ClassLoaderFilter 則只是在主功能上添加了功能善榛,更改當前線程的 ClassLoader,這是典型的裝飾器模式呻畸。

觀察者模式

Dubbo 的 Provider 啟動時移盆,需要與注冊中心交互,先注冊自己的服務伤为,再訂閱自己的服務咒循,訂閱時,采用了觀察者模式绞愚,開啟一個 listener叙甸。注冊中心會每 5 秒定時檢查是否有服務更新,如果有更新位衩,向該服務的提供者發(fā)送一個 notify 消息裆蒸,provider 接受到 notify 消息后,運行 NotifyListener 的 notify 方法蚂四,執(zhí)行監(jiān)聽器方法光戈。

動態(tài)代理模式

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

運維管理

服務上線怎么兼容舊版本烂琴?

可以用版本號(version)過渡,多個不同版本的服務注冊到注冊中心蜕乡,版本號不同的服務相互間不引用奸绷。這個和服務分組的概念有一點類似。

Dubbo telnet 命令能做什么层玲?

dubbo 服務發(fā)布之后号醉,我們可以利用 telnet 命令進行調(diào)試、管理辛块。Dubbo2.0.5 以上版本服務提供端口支持 telnet 命令

Dubbo 支持服務降級嗎畔派?

以通過 dubbo:reference 中設置 mock=“return null”。mock 的值也可以修改為 true润绵,然后再跟接口同一個路徑下實現(xiàn)一個 Mock 類线椰,命名規(guī)則是 “接口名稱+Mock” 后綴。然后在 Mock 類里實現(xiàn)自己的降級邏輯

Dubbo 如何優(yōu)雅停機尘盼?

Dubbo 是通過 JDK 的 ShutdownHook 來完成優(yōu)雅停機的憨愉,所以如果使用kill -9 PID 等強制關閉指令,是不會執(zhí)行優(yōu)雅停機的卿捎,只有通過 kill PID 時莱衩,才會執(zhí)行。

SPI

Dubbo SPI 和 Java SPI 區(qū)別娇澎?

JDK SPI

JDK 標準的 SPI 會一次性加載所有的擴展實現(xiàn)笨蚁,如果有的擴展很耗時,但也沒用上趟庄,很浪費資源括细。所以只希望加載某個的實現(xiàn),就不現(xiàn)實了

DUBBO SPI

1戚啥、對 Dubbo 進行擴展奋单,不需要改動 Dubbo 的源碼

2、延遲加載猫十,可以一次只加載自己想要加載的擴展實現(xiàn)览濒。

3、增加了對擴展點 IOC 和 AOP 的支持拖云,一個擴展點可以直接 setter 注入其

它擴展點贷笛。

4、Dubbo 的擴展機制能很好的支持第三方 IoC 容器宙项,默認支持 Spring Bean乏苦。

其他

Dubbo 支持分布式事務嗎?

目前暫時不支持,可與通過 tcc-transaction 框架實現(xiàn)

介紹:tcc-transaction 是開源的 TCC 補償性分布式事務框架

TCC-Transaction 通過 Dubbo 隱式傳參的功能汇荐,避免自己對業(yè)務代碼的入侵洞就。

Dubbo 可以對結(jié)果進行緩存嗎?

為了提高數(shù)據(jù)訪問的速度掀淘。Dubbo 提供了聲明式緩存旬蟋,以減少用戶加緩存的工作量<dubbo:reference cache=“true” />

其實比普通的配置文件就多了一個標簽 cache=“true”

Dubbo 必須依賴的包有哪些?

Dubbo 必須依賴 JDK革娄,其他為可選咖为。

Dubbo 支持哪些序列化方式?

默認使用 Hessian 序列化稠腊,還有 Duddo躁染、FastJson、Java 自帶序列化架忌。

Dubbo 在安全方面有哪些措施吞彤?

  • Dubbo 通過 Token 令牌防止用戶繞過注冊中心直連,然后在注冊中心上管理授權(quán)叹放。
  • Dubbo 還提供服務黑白名單饰恕,來控制服務所允許的調(diào)用方。

服務調(diào)用是阻塞的嗎井仰?

默認是阻塞的埋嵌,可以異步調(diào)用,沒有返回值的可以這么做俱恶。Dubbo 是基于 NIO 的非阻塞實現(xiàn)并行調(diào)用雹嗦,客戶端不需要啟動多線程即可完成并行調(diào)用多個遠程服務,相對多線程開銷較小合是,異步調(diào)用會返回一個 Future 對象了罪。

服務提供者能實現(xiàn)失效踢出是什么原理?

服務失效踢出基于 zookeeper 的臨時節(jié)點原理聪全。

同一個服務多個注冊的情況下可以直連某一個服務嗎泊藕?

可以點對點直連,修改配置即可难礼,也可以通過 telnet 直接某個服務娃圆。

Dubbo 服務降級,失敗重試怎么做蛾茉?

可以通過 dubbo:reference 中設置 mock=“return null”讼呢。mock 的值也可以修改為 true,然后再跟接口同一個路徑下實現(xiàn)一個 Mock 類臀稚,命名規(guī)則是 “接口名稱+Mock” 后綴吝岭。然后在 Mock 類里實現(xiàn)自己的降級邏輯

Dubbo 使用過程中都遇到了些什么問題三痰?

在注冊中心找不到對應的服務,檢查 service 實現(xiàn)類是否添加了@service 注解無法連接到注冊中心,檢查配置文件中的對應的測試 ip 是否正確

RPC

為什么要有RPC

http接口是在接口不多吧寺、系統(tǒng)與系統(tǒng)交互較少的情況下窜管,解決信息孤島初期常使用的一種通信手段;優(yōu)點就是簡單稚机、直接幕帆、開發(fā)方便。利用現(xiàn)成的http協(xié)議進行傳輸赖条。但是如果是一個大型的網(wǎng)站失乾,內(nèi)部子系統(tǒng)較多、接口非常多的情況下纬乍,RPC框架的好處就顯示出來了碱茁,首先就是長鏈接,不必每次通信都要像http一樣去3次握手什么的仿贬,減少了網(wǎng)絡開銷纽竣;其次就是RPC框架一般都有注冊中心,有豐富的監(jiān)控管理茧泪;發(fā)布蜓氨、下線接口、動態(tài)擴展等队伟,對調(diào)用方來說是無感知穴吹、統(tǒng)一化的操作。第三個來說就是安全性嗜侮。最后就是最近流行的服務化架構(gòu)港令、服務化治理,RPC框架是一個強力的支撐锈颗。

socket只是一個簡單的網(wǎng)絡通信方式缠借,只是創(chuàng)建通信雙方的通信通道,而要實現(xiàn)rpc的功能宜猜,還需要對其進行封裝泼返,以實現(xiàn)更多的功能。

RPC一般配合netty框架姨拥、spring自定義注解來編寫輕量級框架绅喉,其實netty內(nèi)部是封裝了socket的,較新的jdk的IO一般是NIO叫乌,即非阻塞IO柴罐,在高并發(fā)網(wǎng)站中,RPC的優(yōu)勢會很明顯

什么是RPC

RPC(Remote Procedure Call Protocol)遠程過程調(diào)用協(xié)議憨奸,它是一種通過網(wǎng)絡從遠程計算機程序上請求服務革屠,而不需要了解底層網(wǎng)絡技術(shù)的協(xié)議。簡言之,RPC使得程序能夠像訪問本地系統(tǒng)資源一樣似芝,去訪問遠端系統(tǒng)資源那婉。比較關鍵的一些方面包括:通訊協(xié)議、序列化党瓮、資源(接口)描述详炬、服務框架、性能寞奸、語言支持等呛谜。

簡單的說,RPC就是從一臺機器(客戶端)上通過參數(shù)傳遞的方式調(diào)用另一臺機器(服務器)上的一個函數(shù)或方法(可以統(tǒng)稱為服務)并得到返回的結(jié)果枪萄。

PRC架構(gòu)組件

一個基本的RPC架構(gòu)里面應該至少包含以下4個組件:

1隐岛、客戶端(Client):服務調(diào)用方(服務消費者)

2、客戶端存根(Client Stub):存放服務端地址信息瓷翻,將客戶端的請求參數(shù)數(shù)據(jù)信息打包成網(wǎng)絡消息礼仗,再通過網(wǎng)絡傳輸發(fā)送給服務端

3、服務端存根(Server Stub):接收客戶端發(fā)送過來的請求消息并進行解包逻悠,然后再調(diào)用本地服務進行處理

4元践、服務端(Server):服務的真正提供者

具體調(diào)用過程

1、服務消費者(client客戶端)通過調(diào)用本地服務的方式調(diào)用需要消費的服務童谒;

2单旁、客戶端存根(client stub)接收到調(diào)用請求后負責將方法、入?yún)⒌刃畔⑿蛄谢ńM裝)成能夠進行網(wǎng)絡傳輸?shù)南Ⅲw饥伊;

3象浑、客戶端存根(client stub)找到遠程的服務地址,并且將消息通過網(wǎng)絡發(fā)送給服務端琅豆;

4愉豺、服務端存根(server stub)收到消息后進行解碼(反序列化操作);

5茫因、服務端存根(server stub)根據(jù)解碼結(jié)果調(diào)用本地的服務進行相關處理蚪拦;

6、本地服務執(zhí)行具體業(yè)務邏輯并將處理結(jié)果返回給服務端存根(server stub)冻押;

7驰贷、服務端存根(server stub)將返回結(jié)果重新打包成消息(序列化)并通過網(wǎng)絡發(fā)送至消費方;

8洛巢、客戶端存根(client stub)接收到消息括袒,并進行解碼(反序列化);

9稿茉、服務消費方得到最終結(jié)果锹锰;

而RPC框架的實現(xiàn)目標則是將上面的第2-10步完好地封裝起來芥炭,也就是把調(diào)用、編碼/解碼的過程給封裝起來恃慧,讓用戶感覺上像調(diào)用本地服務一樣的調(diào)用遠程服務园蝠。

RPC和SOA、SOAP糕伐、REST的區(qū)別

1砰琢、REST

可以看著是HTTP協(xié)議的一種直接應用蘸嘶,默認基于JSON作為傳輸格式,使用簡單,學習成本低效率高,但是安全性較低良瞧。

2、SOAP

SOAP是一種數(shù)據(jù)交換協(xié)議規(guī)范,是一種輕量的训唱、簡單的褥蚯、基于XML的協(xié)議的規(guī)范。而SOAP可以看著是一個重量級的協(xié)議况增,基于XML赞庶、SOAP在安全方面是通過使用XML-Security和XML-Signature兩個規(guī)范組成了WS-Security來實現(xiàn)安全控制的,當前已經(jīng)得到了各個廠商的支持 。

它有什么優(yōu)點澳骤?簡單總結(jié)為:易用歧强、靈活、跨語言为肮、跨平臺摊册。

3、SOA

面向服務架構(gòu)颊艳,它可以根據(jù)需求通過網(wǎng)絡對松散耦合的粗粒度應用組件進行分布式部署茅特、組合和使用。服務層是SOA的基礎棋枕,可以直接被應用調(diào)用白修,從而有效控制系統(tǒng)中與軟件代理交互的人為依賴性。

SOA是一種粗粒度重斑、松耦合服務架構(gòu)兵睛,服務之間通過簡單、精確定義接口進行通訊窥浪,不涉及底層編程接口和通訊模型卤恳。SOA可以看作是B/S模型、XML(標準通用標記語言的子集)/Web Service技術(shù)之后的自然延伸寒矿。

4突琳、REST 和 SOAP、RPC 有何區(qū)別呢?

沒什么太大區(qū)別符相,他們的本質(zhì)都是提供可支持分布式的基礎服務拆融,最大的區(qū)別在于他們各自的的特點所帶來的不同應用場景 蠢琳。

RPC框架需要解決的問題?

1镜豹、如何確定客戶端和服務端之間的通信協(xié)議傲须?

2、如何更高效地進行網(wǎng)絡通信趟脂?

3泰讽、服務端提供的服務如何暴露給客戶端?

4昔期、客戶端如何發(fā)現(xiàn)這些暴露的服務已卸?

5、如何更高效地對請求對象和響應結(jié)果進行序列化和反序列化操作硼一?

RPC的實現(xiàn)基礎累澡?

1、需要有非常高效的網(wǎng)絡通信般贼,比如一般選擇Netty作為網(wǎng)絡通信框架愧哟;

2、需要有比較高效的序列化框架哼蛆,比如谷歌的Protobuf序列化框架蕊梧;

3、可靠的尋址方式(主要是提供服務的發(fā)現(xiàn))腮介,比如可以使用Zookeeper來注冊服務等等肥矢;

4、如果是帶會話(狀態(tài))的RPC調(diào)用萤厅,還需要有會話和狀態(tài)保持的功能橄抹;

RPC使用了哪些關鍵技術(shù)?

1惕味、動態(tài)代理

生成Client Stub(客戶端存根)和Server Stub(服務端存根)的時候需要用到Java動態(tài)代理技術(shù)楼誓,可以使用JDK提供的原生的動態(tài)代理機制,也可以使用開源的:CGLib代理名挥,Javassist字節(jié)碼生成技術(shù)疟羹。

2、序列化和反序列化

在網(wǎng)絡中禀倔,所有的數(shù)據(jù)都將會被轉(zhuǎn)化為字節(jié)進行傳送榄融,所以為了能夠使參數(shù)對象在網(wǎng)絡中進行傳輸,需要對這些參數(shù)進行序列化和反序列化操作救湖。

  • 序列化:把對象轉(zhuǎn)換為字節(jié)序列的過程稱為對象的序列化愧杯,也就是編碼的過程。
  • 反序列化:把字節(jié)序列恢復為對象的過程稱為對象的反序列化鞋既,也就是解碼的過程力九。

目前比較高效的開源序列化框架:如Kryo耍铜、FastJson和Protobuf等。

3跌前、NIO通信

出于并發(fā)性能的考慮棕兼,傳統(tǒng)的阻塞式 IO 顯然不太合適,因此我們需要異步的 IO抵乓,即 NIO伴挚。Java 提供了 NIO 的解決方案,Java 7 也提供了更優(yōu)秀的 NIO.2 支持灾炭【ビ螅可以選擇Netty或者MINA來解決NIO數(shù)據(jù)傳輸?shù)膯栴}。

4咆贬、服務注冊中心

可選:Redis爷速、Zookeeper膏孟、Consul 再层、Etcd雄右。一般使用ZooKeeper提供服務注冊與發(fā)現(xiàn)功能库糠,解決單點故障以及分布式部署的問題(注冊中心)钮追。

主流RPC框架有哪些

1怒炸、RMI

利用java.rmi包實現(xiàn)隅俘,基于Java遠程方法協(xié)議(Java Remote Method Protocol) 和java的原生序列化沈自。

2酌儒、Hessian

是一個輕量級的remoting onhttp工具,使用簡單的方法提供了RMI的功能枯途。 基于HTTP協(xié)議忌怎,采用二進制編解碼。

3酪夷、protobuf-rpc-pro

是一個Java類庫榴啸,提供了基于 Google 的 Protocol Buffers 協(xié)議的遠程方法調(diào)用的框架⊥砹耄基于 Netty 底層的 NIO 技術(shù)鸥印。支持 TCP 重用/ keep-alive、SSL加密坦报、RPC 調(diào)用取消操作库说、嵌入式日志等功能。

4片择、Thrift

是一種可伸縮的跨語言服務的軟件框架潜的。它擁有功能強大的代碼生成引擎,無縫地支持C + +字管,C#啰挪,Java疏咐,Python和PHP和Ruby。thrift允許你定義一個描述文件脐供,描述數(shù)據(jù)類型和服務接口浑塞。依據(jù)該文件,編譯器方便地生成RPC客戶端和服務器通信代碼政己。

最初由facebook開發(fā)用做系統(tǒng)內(nèi)個語言之間的RPC通信酌壕,2007年由facebook貢獻到apache基金 ,現(xiàn)在是apache下的opensource之一 歇由。支持多種語言之間的RPC方式的通信:php語言client可以構(gòu)造一個對象卵牍,調(diào)用相應的服務方法來調(diào)用java語言的服務,跨越語言的C/S RPC調(diào)用沦泌。底層通訊基于SOCKET糊昙。

5、Avro

出自Hadoop之父Doug Cutting, 在Thrift已經(jīng)相當流行的情況下推出Avro的目標不僅是提供一套類似Thrift的通訊中間件,更是要建立一個新的谢谦,標準性的云計算的數(shù)據(jù)交換和存儲的Protocol释牺。支持HTTP,TCP兩種協(xié)議回挽。

6没咙、Dubbo

Dubbo是 阿里巴巴公司開源的一個高性能優(yōu)秀的服務框架,使得應用可通過高性能的 RPC 實現(xiàn)服務的輸出和輸入功能千劈,可以和 Spring框架無縫集成祭刚。

RPC的實現(xiàn)原理架構(gòu)圖

PS:這張圖非常重點,是PRC的基本原理墙牌,請大家一定記孜型浴!

也就是說兩臺服務器A喜滨,B捉捅,一個應用部署在A服務器上,想要調(diào)用B服務器上應用提供的函數(shù)/方法鸿市,由于不在一個內(nèi)存空間锯梁,不能直接調(diào)用,需要通過網(wǎng)絡來表達調(diào)用的語義和傳達調(diào)用的數(shù)據(jù)焰情。

比如說陌凳,A服務器想調(diào)用B服務器上的一個方法:

User getUserByName(String userName)

1、建立通信

首先要解決通訊的問題:即A機器想要調(diào)用B機器内舟,首先得建立起通信連接合敦。

主要是通過在客戶端和服務器之間建立TCP連接,遠程過程調(diào)用的所有交換的數(shù)據(jù)都在這個連接里傳輸验游。連接可以是按需連接充岛,調(diào)用結(jié)束后就斷掉保檐,也可以是長連接,多個遠程過程調(diào)用共享同一個連接崔梗。

通常這個連接可以是按需連接(需要調(diào)用的時候就先建立連接夜只,調(diào)用結(jié)束后就立馬斷掉),也可以是長連接(客戶端和服務器建立起連接之后保持長期持有蒜魄,不管此時有無數(shù)據(jù)包的發(fā)送扔亥,可以配合心跳檢測機制定期檢測建立的連接是否存活有效),多個遠程過程調(diào)用共享同一個連接谈为。

2旅挤、服務尋址

要解決尋址的問題,也就是說伞鲫,A服務器上的應用怎么告訴底層的RPC框架粘茄,如何連接到B服務器(如主機或IP地址)以及特定的端口,方法的名稱名稱是什么秕脓。

通常情況下我們需要提供B機器(主機名或IP地址)以及特定的端口柒瓣,然后指定調(diào)用的方法或者函數(shù)的名稱以及入?yún)⒊鰠⒌刃畔ⅲ@樣才能完成服務的一個調(diào)用撒会。

可靠的尋址方式(主要是提供服務的發(fā)現(xiàn))是RPC的實現(xiàn)基石嘹朗,比如可以采用Redis或者Zookeeper來注冊服務等等师妙。

2.1诵肛、從服務提供者的角度看

當服務提供者啟動的時候,需要將自己提供的服務注冊到指定的注冊中心默穴,以便服務消費者能夠通過服務注冊中心進行查找怔檩;

當服務提供者由于各種原因致使提供的服務停止時,需要向注冊中心注銷停止的服務蓄诽;

服務的提供者需要定期向服務注冊中心發(fā)送心跳檢測薛训,服務注冊中心如果一段時間未收到來自服務提供者的心跳后,認為該服務提供者已經(jīng)停止服務仑氛,則將該服務從注冊中心上去掉乙埃。

2.2、從調(diào)用者的角度看

服務的調(diào)用者啟動的時候根據(jù)自己訂閱的服務向服務注冊中心查找服務提供者的地址等信息锯岖;

當服務調(diào)用者消費的服務上線或者下線的時候介袜,注冊中心會告知該服務的調(diào)用者;

服務調(diào)用者下線的時候出吹,則取消訂閱遇伞。

3、網(wǎng)絡傳輸

3.1捶牢、序列化

當A機器上的應用發(fā)起一個RPC調(diào)用時鸠珠,調(diào)用方法和其入?yún)⒌刃畔⑿枰ㄟ^底層的網(wǎng)絡協(xié)議如TCP傳輸?shù)紹機器巍耗,由于網(wǎng)絡協(xié)議是基于二進制的,所有我們傳輸?shù)膮?shù)數(shù)據(jù)都需要先進行序列化(Serialize)或者編組(marshal)成二進制的形式才能在網(wǎng)絡中進行傳輸渐排。然后通過尋址操作和網(wǎng)絡傳輸將序列化或者編組之后的二進制數(shù)據(jù)發(fā)送給B機器炬太。

3.2、反序列化

當B機器接收到A機器的應用發(fā)來的請求之后驯耻,又需要對接收到的參數(shù)等信息進行反序列化操作(序列化的逆操作)娄琉,即將二進制信息恢復為內(nèi)存中的表達方式,然后再找到對應的方法(尋址的一部分)進行本地調(diào)用(一般是通過生成代理Proxy去調(diào)用, 通常會有JDK動態(tài)代理吓歇、CGLIB動態(tài)代理孽水、Javassist生成字節(jié)碼技術(shù)等),之后得到調(diào)用的返回值城看。

4女气、服務調(diào)用

B機器進行本地調(diào)用(通過代理Proxy和反射調(diào)用)之后得到了返回值,此時還需要再把返回值發(fā)送回A機器测柠,同樣也需要經(jīng)過序列化操作炼鞠,然后再經(jīng)過網(wǎng)絡傳輸將二進制數(shù)據(jù)發(fā)送回A機器,而當A機器接收到這些返回值之后轰胁,則再次進行反序列化操作谒主,恢復為內(nèi)存中的表達方式,最后再交給A機器上的應用進行相關處理(一般是業(yè)務邏輯處理操作)赃阀。

通常霎肯,經(jīng)過以上四個步驟之后,一次完整的RPC調(diào)用算是完成了榛斯,另外可能因為網(wǎng)絡抖動等原因需要重試等观游。

來源:https://thinkwon.blog.csdn.net/

作者:thinkwon

本文首發(fā)于公眾號:Java版web項目,歡迎關注獲取更多精彩內(nèi)容

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末驮俗,一起剝皮案震驚了整個濱河市懂缕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌王凑,老刑警劉巖搪柑,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異索烹,居然都是意外死亡工碾,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進店門术荤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來倚喂,“玉大人,你說我怎么就攤上這事《巳Γ” “怎么了焦读?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長舱权。 經(jīng)常有香客問我矗晃,道長,這世上最難降的妖魔是什么宴倍? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任张症,我火速辦了婚禮,結(jié)果婚禮上鸵贬,老公的妹妹穿的比我還像新娘俗他。我一直安慰自己,他們只是感情好阔逼,可當我...
    茶點故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布兆衅。 她就那樣靜靜地躺著,像睡著了一般嗜浮。 火紅的嫁衣襯著肌膚如雪羡亩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天危融,我揣著相機與錄音畏铆,去河邊找鬼。 笑死吉殃,一個胖子當著我的面吹牛辞居,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播寨腔,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼速侈,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了迫卢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤冶共,失蹤者是張志新(化名)和其女友劉穎乾蛤,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捅僵,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡家卖,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了庙楚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片上荡。...
    茶點故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酪捡,到底是詐尸還是另有隱情叁征,我是刑警寧澤,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布逛薇,位于F島的核電站捺疼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏永罚。R本人自食惡果不足惜啤呼,卻給世界環(huán)境...
    茶點故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呢袱。 院中可真熱鬧官扣,春花似錦、人聲如沸羞福。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坯临。三九已至焊唬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間看靠,已是汗流浹背赶促。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留挟炬,地道東北人鸥滨。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像谤祖,于是被迫代替她去往敵國和親婿滓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,647評論 2 354

推薦閱讀更多精彩內(nèi)容