秒懂Dubbo接口原理篇

      網友投稿 857 2022-05-29

      引言

      背景

      單一應用架構

      垂直應用架構

      分布式服務架構

      流動計算架構

      引言

      背景

      單一應用架構

      垂直應用架構

      分布式服務架構

      流動計算架構

      為什么要用 Dubbo?

      什么是分布式?

      為什么要分布式?

      Dubbo 的架構

      Dubbo 的架構圖解

      Dubbo 工作原理

      Dubbo 的負載均衡策略

      先來解釋一下什么是負載均衡

      再來看看 Dubbo 提供的負載均衡策略

      Random LoadBalance(默認,基于權重的隨機負載均衡機制)

      RoundRobin LoadBalance(不推薦,基于權重的輪詢負載均衡機制)

      LeastActive LoadBalance

      ConsistentHash LoadBalance

      配置方式

      zookeeper宕機與dubbo直連的情況

      引言

      在上文性能基礎之常見RPC框架淺析中我們詳細介紹常見的RPC框架,本文將詳細介紹Dubbo接口。

      背景

      隨著互聯網的發展,網站應用的規模不斷擴大,常規的垂直應用架構已無法應對,分布式服務架構以及流動計算架構勢在必行,亟需一個治理系統確保架構有條不紊的演進。

      單一應用架構

      當網站流量很小時,只需一個應用,將所有功能都部署在一起,以減少部署節點和成本。此時,用于簡化增刪改查工作量的數據訪問框架(ORM)是關鍵。

      垂直應用架構

      當訪問量逐漸增大,單一應用增加機器帶來的加速度越來越小,將應用拆成互不相干的幾個應用,以提升效率。此時,用于加速前端頁面開發的Web框架(MVC)是關鍵。

      分布式服務架構

      當垂直應用越來越多,應用之間交互不可避免,將核心業務抽取出來,作為獨立的服務,逐漸形成穩定的服務中心,使前端應用能更快速的響應多變的市場需求。此時,用于提高業務復用及整合的分布式服務框架(RPC)是關鍵。

      流動計算架構

      當服務越來越多,容量的評估,小服務資源的浪費等問題逐漸顯現,此時需增加一個調度中心基于訪問壓力實時管理集群容量,提高集群利用率。此時,用于提高機器利用率的資源調度和治理中心(SOA)是關鍵。

      為什么要用 Dubbo?

      Dubbo 的誕生和 SOA 分布式架構的流行有著莫大的關系。SOA 面向服務的架構(Service Oriented Architecture),也就是把工程按照業務邏輯拆分成服務層、表現層兩個工程。服務層中包含業務邏輯,只需要對外提供服務即可。表現層只需要處理和頁面的交互,業務邏輯都是調用服務層的服務來實現。SOA架構中有兩個主要角色:服務提供者(Provider)和服務使用者(Consumer)。

      如果你要開發分布式程序,你也可以直接基于 HTTP 接口進行通信,但是為什么要用 Dubbo呢?

      我覺得主要可以從 Dubbo 提供的下面四點特性來說為什么要用 Dubbo:

      負載均衡——同一個服務部署在不同的機器時該調用那一臺機器上的服務

      服務調用鏈路生成——隨著系統的發展,服務越來越多,服務間依賴關系變得錯蹤復雜,甚至分不清哪個應用要在哪個應用之前啟動,架構師都不能完整的描述應用的架構關系。Dubbo 可以為我們解決服務之間互相是如何調用的。

      服務訪問壓力以及時長統計、資源調度和治理——基于訪問壓力實時管理集群容量,提高集群利用率。

      服務降級——某個服務掛掉之后調用備用服務

      另外,Dubbo 除了能夠應用在分布式系統中,也可以應用在現在比較火的微服務系統中。不過,由于 Spring Cloud 在微服務中應用更加廣泛,所以,我覺得一般我們提 Dubbo 的話,大部分是分布式系統的情況。

      我們剛剛提到了分布式這個概念,下面再給大家介紹一下什么是分布式?為什么要分布式?

      什么是分布式?

      分布式或者說 SOA 分布式重要的就是面向服務,說簡單的分布式就是我們把整個系統拆分成不同的服務然后將這些服務放在不同的服務器上減輕單體服務的壓力提高并發量和性能。比如電商系統可以簡單地拆分成訂單系統、商品系統、登錄系統等等,拆分之后的每個服務可以部署在不同的機器上,如果某一個服務的訪問量比較大的話也可以將這個服務同時部署在多臺機器上。

      為什么要分布式?

      從開發角度來講單體應用的代碼都集中在一起,而分布式系統的代碼根據業務被拆分。所以,每個團隊可以負責一個服務的開發,這樣提升了開發效率。另外,代碼根據業務拆分之后更加便于維護和擴展。

      另外,我覺得將系統拆分成分布式之后不光便于系統擴展和維護,更能提高整個系統的性能。你想一想嘛?把整個系統拆分成不同的服務/系統,然后每個服務/系統 單獨部署在一臺服務器上,是不是很大程度上提高了系統性能呢?

      Dubbo 的架構

      Dubbo 的架構圖解

      述節點簡單說明:

      Provider: 暴露服務的服務提供方

      Consumer: 調用遠程服務的服務消費方

      Registry: 服務注冊與發現的注冊中心

      Monitor: 統計服務的調用次數和調用時間的監控中心

      Container: 服務運行容器

      調用關系說明:

      服務容器負責啟動,加載,運行服務提供者。

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

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

      注冊中心返回服務提供者地址列表給消費者,如果有變更,注冊中心將基于長連接推送變更數據給消費者。

      服務消費者,從提供者地址列表中,基于軟負載均衡算法,選一臺提供者進行調用,如果調用失敗,再選另一臺調用。

      服務消費者和提供者,在內存中累計調用次數和調用時間,定時每分鐘8. 發送一次統計數據到監控中心。

      重要知識點總結:

      注冊中心負責服務地址的注冊與查找,相當于目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小

      監控中心負責統計各服務調用次數,調用時間等,統計先在內存匯總后每分鐘一次發送到監控中心服務器,并以報表展示

      注冊中心,服務提供者,服務消費者三者之間均為長連接,監控中心除外

      注冊中心通過長連接感知服務提供者的存在,服務提供者宕機,注冊中心將立即推送事件通知消費者

      注冊中心和監控中心全部宕機,不影響已運行的提供者和消費者,消費者在本地緩存了提供者列表

      注冊中心和監控中心都是可選的,服務消費者可以直連服務提供者

      服務提供者無狀態,任意一臺宕掉后,不影響使用

      服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復

      Dubbo 工作原理

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

      各層說明:

      第一層:service層,接口層,給服務提供者和消費者來實現的

      第二層:config層,配置層,主要是對dubbo進行各種配置的

      第三層:proxy層,服務接口透明代理,生成服務的客戶端 Stub 和服務器端 Skeleton

      第四層:registry層,服務注冊層,負責服務的注冊與發現

      第五層:cluster層,集群層,封裝多個服務提供者的路由以及負載均衡,將多個實例組合成一個服務

      第六層:monitor層,監控層,對rpc接口的調用次數和調用時間進行監控

      第七層:protocol層,遠程調用層,封裝rpc調用

      第八層:exchange層,信息交換層,封裝請求響應模式,同步轉異步

      第九層:transport層,網絡傳輸層,抽象mina和netty為統一接口

      第十層:serialize層,數據序列化層。網絡傳輸需要。

      從上圖可以看出,Dubbo對于服務提供方和服務消費方,從框架的10層中分別提供了各自需要關心和擴展的接口,構建整個服務生態系統(服務提供方和服務消費方本身就是一個以服務為中心的)。

      根據官方提供的,對于上述各層之間關系的描述,如下所示:

      在 RPC 中,Protocol 是核心層,也就是只要有Protocol + Invoker + Exporter 就可以完成非透明的RPC調用,然后在Invoker的主過程上Filter攔截點。

      圖中的 Consumer 和Provider是抽象概念,只是想讓看圖者更直觀的了解哪些類分屬于客戶端與服務器端,不用Client和Server的原因是Dubbo在很多場景下都使用Provider、Consumer、Registry、Monitor劃分邏輯拓普節點,保持統一概念。

      而Cluster是外圍概念,所以Cluster的目的是將多個Invoker偽裝成一個Invoker,這樣其它人只要關注Protocol層Invoker即可,加上Cluster或者去掉Cluster對其它層都不會造成影響,因為只有一個提供者時,是不需要Cluster的。

      Proxy層封裝了所有接口的透明化代理,而在其它層都以Invoker為中心,只有到了暴露給用戶使用時,才用Proxy將Invoker轉成接口,或將接口實現轉成Invoker,也就是去掉Proxy層RPC是可以Run的,只是不那么透明,不那么看起來像調本地服務一樣調遠程服務。

      而Remoting 實現是Dubbo協議的實現,如果你選擇RMI協議,整個Remoting都不會用上,Remoting內部再劃為Transport傳輸層和Exchange信息交換層,Transport層只負責單向消息傳輸,是對Mina、Netty、Grizzly的抽象,它也可以擴展UDP傳輸,而Exchange層是在傳輸層之上封裝了Request-Response語義。

      Registry和Monitor實際上不算一層,而是一個獨立的節點,只是為了全局概覽,用層的方式畫在一起。

      從上面的架構圖中,我們可以了解到,Dubbo作為一個分布式服務框架,主要具有如下幾個核心的要點:

      服務定義

      服務是圍繞服務提供方和服務消費方的,服務提供方實現服務,而服務消費方調用服務。

      服務注冊

      對于服務提供方,它需要發布服務,而且由于應用系統的復雜性,服務的數量、類型也不斷膨脹;對于服務消費方,它最關心如何獲取到它所需要的服務,而面對復雜的應用系統,需要管理大量的服務調用。而且,對于服務提供方和服務消費方來說,他們還有可能兼具這兩種角色,即既需要提供服務,有需要消費服務。

      通過將服務統一管理起來,可以有效地優化內部應用對服務發布/使用的流程和管理。服務注冊中心可以通過特定協議來完成服務對外的統一。

      Dubbo提供的注冊中心有如下幾種類型可供選擇:

      Multicast注冊中心

      Zookeeper注冊中心

      Redis注冊中心

      Simple注冊中心

      服務監控

      無論是服務提供方,還是服務消費方,他們都需要對服務調用的實際狀態進行有效的監控,從而改進服務質量。

      遠程通信與信息交換

      遠程通信需要指定通信雙方所約定的協議,在保證通信雙方理解協議語義的基礎上,還要保證高效、穩定的消息傳輸。Dubbo繼承了當前主流的網絡通信框架,主要包括如下幾個:

      Mina

      Netty

      Grizzly

      服務調用

      下面從Dubbo官網直接拿來,看一下基于RPC層,服務提供方和服務消費方之間的調用關系,如圖所示:

      上圖中,藍色的表示與業務有交互,綠色的表示只對Dubbo內部交互。上述圖所描述的調用流程如下:

      服務提供方發布服務到服務注冊中心;

      服務消費方從服務注冊中心訂閱服務;

      服務消費方調用已經注冊的可用服務

      接著,將上面抽象的調用流程圖展開,詳細如圖所示:

      注冊/注銷服務

      服務的注冊與注銷,是對服務提供方角色而言,那么注冊服務與注銷服務的時序圖,如圖所示:

      服務訂閱/取消

      為了滿足應用系統的需求,服務消費方的可能需要從服務注冊中心訂閱指定的有服務提供方發布的服務,在得到通知可以使用服務時,就可以直接調用服務。反過來,如果不需要某一個服務了,可以取消該服務。下面看一下對應的時序圖,如圖所示:

      協議支持

      Dubbo支持多種協議,如下所示:

      Dubbo協議

      Hessian協議

      HTTP協議

      RMI協議

      WebService協議

      Thrift協議

      Memcached協議

      Redis協議

      在通信過程中,不同的服務等級一般對應著不同的服務質量,那么選擇合適的協議便是一件非常重要的事情。你可以根據你應用的創建來選擇。例如,使用RMI協議,一般會受到防火墻的限制,所以對于外部與內部進行通信的場景,就不要使用RMI協議,而是基于HTTP協議或者Hessian協議。

      參考補充

      Dubbo以包結構來組織各個模塊,各個模塊及其關系,如圖所示:

      可以通過Dubbo的代碼(使用Maven管理)組織,與上面的模塊進行比較。簡單說明各個包的情況:

      dubbo-common 公共邏輯模塊,包括Util類和通用模型。

      dubbo-remoting 遠程通訊模塊,相當于Dubbo協議的實現,如果RPC用RMI協議則不需要使用此包。

      dubbo-rpc 遠程調用模塊,抽象各種協議,以及動態代理,只包含一對一的調用,不關心集群的管理。

      dubbo-cluster 集群模塊,將多個服務提供方偽裝為一個提供方,包括:負載均衡、容錯、路由等,集群的地址列表可以是靜態配置的,也可以是由注冊中心下發。

      dubbo-registry 注冊中心模塊,基于注冊中心下發地址的集群方式,以及對各種注冊中心的抽象。

      dubbo-monitor 監控模塊,統計服務調用次數,調用時間的,調用鏈跟蹤的服務。

      dubbo-config 配置模塊,是Dubbo對外的API,用戶通過Config使用Dubbo,隱藏Dubbo所有細節。

      秒懂Dubbo接口(原理篇)

      dubbo-container 容器模塊,是一個Standalone的容器,以簡單的Main加載Spring啟動,因為服務通常不需要Tomcat/JBoss等Web容器的特性,沒必要用Web容器去加載服務。

      Dubbo 的負載均衡策略

      先來解釋一下什么是負載均衡

      先來個官方的解釋。

      維基百科對負載均衡的定義:負載均衡改善了跨多個計算資源(例如計算機,計算機集群,網絡鏈接,中央處理單元或磁盤驅動的的工作負載分布。負載平衡旨在優化資源使用,最大化吞吐量,最小化響應時間,并避免任何單個資源的過載。使用具有負載平衡而不是單個組件的多個組件可以通過冗余提高可靠性和可用性。負載平衡通常涉及專用軟件或硬件

      上面講的大家可能不太好理解,再用通俗的話給大家說一下。

      比如我們的系統中的某個服務的訪問量特別大,我們將這個服務部署在了多臺服務器上,當客戶端發起請求的時候,多臺服務器都可以處理這個請求。那么,如何正確選擇處理該請求的服務器就很關鍵。假如,你就要一臺服務器來處理該服務的請求,那該服務部署在多臺服務器的意義就不復存在了。負載均衡就是為了避免單個服務器響應同一請求,容易造成服務器宕機、崩潰等問題,我們從負載均衡的這四個字就能明顯感受到它的意義。

      再來看看 Dubbo 提供的負載均衡策略

      在集群負載均衡時,Dubbo 提供了多種均衡策略,默認為 random 隨機調用??梢宰孕袛U展負載均衡策略,參見:負載均衡擴展。

      隨機,按權重設置隨機概率。

      在一個截面上碰撞的概率高,但調用量越大分布越均勻,而且按概率使用權重后也比較均勻,有利于動態調整提供者權重。

      輪循,按公約后的權重設置輪循比率。

      存在慢的提供者累積請求的問題,比如:第二臺機器很慢,但沒掛,當請求調到第二臺時就卡在那,久而久之,所有請求都卡在調到第二臺上。

      最少活躍調用數,相同活躍數的隨機,活躍數指調用前后計數差。

      使慢的提供者收到更少請求,因為越慢的提供者的調用前后計數差會越大。

      一致性 Hash,相同參數的請求總是發到同一提供者。(如果你需要的不是隨機負載均衡,是要一類請求都到一個節點,那就走這個一致性hash策略。)

      當某一臺提供者掛時,原本發往該提供者的請求,基于虛擬節點,平攤到其它提供者,不會引起劇烈變動。

      算法參見:http://en.wikipedia.org/wiki/Consistent_hashing

      缺省只對第一個參數 Hash,如果要修改,請配置

      缺省用 160 份虛擬節點,如果要修改,請配置

      配置方式

      xml 配置方式

      服務端服務級別

      客戶端服務級別

      服務端方法級別

      客戶端方法級別

      注解配置方式:

      消費方基于基于注解的服務級別配置方式:

      @Reference(loadbalance = "roundrobin") HelloService helloService;

      zookeeper宕機與dubbo直連的情況

      zookeeper 宕機與 dubbo 直連的情況在面試中可能會被經常問到,所以要引起重視。

      在實際生產中,假如 zookeeper 注冊中心宕掉,一段時間內服務消費方還是能夠調用提供方的服務的,實際上它使用的本地緩存進行通訊,這只是dubbo健壯性的一種提現。

      dubbo的健壯性表現:

      監控中心宕掉不影響使用,只是丟失部分采樣數據

      數據庫宕掉后,注冊中心仍能通過緩存提供服務列表查詢,但不能注冊新服務

      注冊中心對等集群,任意一臺宕掉后,將自動切換到另一臺

      注冊中心全部宕掉后,服務提供者和服務消費者仍能通過本地緩存通訊

      服務提供者無狀態,任意一臺宕掉后,不影響使用

      服務提供者全部宕掉后,服務消費者應用將無法使用,并無限次重連等待服務提供者恢復

      我們前面提到過:注冊中心負責服務地址的注冊與查找,相當于目錄服務,服務提供者和消費者只在啟動時與注冊中心交互,注冊中心不轉發請求,壓力較小。所以,我們可以完全可以繞過注冊中心——采用 dubbo 直連 ,即在服務消費方配置服務提供方的位置信息。

      xml配置方式:

      注解方式:

      @Reference(url = "127.0.0.1:20880") HelloService helloService;

      參加文獻:

      [1]:http://dubbo.incubator.apache.org/zh-cn/docs/user/quick-start.html

      [2]:https://github.com/Snailclimb/JavaGuide/blob/master/計算機網絡與數據通信/dubbo.md

      Dubbo 負載均衡緩存

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:物體檢測-Faster R-CNN(1)
      下一篇:關于Kubernetes集群中常見問題的排查方法的一些筆記
      相關文章
      亚洲熟女精品中文字幕| 老司机亚洲精品影院无码| 亚洲成人免费在线| 中文字幕亚洲日韩无线码| 亚洲天堂在线视频| 亚洲高清国产拍精品青青草原| 朝桐光亚洲专区在线中文字幕 | 一区二区三区亚洲| 亚洲视频在线观看免费| 久久精品国产亚洲av高清漫画| 日韩亚洲Av人人夜夜澡人人爽| 亚洲黄色免费网址| 亚洲春色在线观看| 亚洲jjzzjjzz在线播放| 亚洲情A成黄在线观看动漫软件 | 亚洲AV一宅男色影视| 久久精品国产亚洲| 99亚洲精品高清一二区| 亚洲视频国产精品| 亚洲av无码专区在线| 亚洲中文字幕乱码熟女在线| 亚洲欧美日韩中文高清www777| 亚洲国产精品成人午夜在线观看| 国产亚洲一卡2卡3卡4卡新区| 亚洲AⅤ无码一区二区三区在线| 亚洲国模精品一区 | 亚洲一级特黄特黄的大片| 亚洲熟妇AV一区二区三区浪潮| 亚洲AV无码一区二区乱子仑| 国产亚洲精品精品精品| 国产成人精品久久亚洲高清不卡 国产成人精品久久亚洲 | 日本亚洲视频在线| 亚洲福利在线观看| 亚洲天堂一区在线| 亚洲人成电影网站色| 亚洲第一区在线观看| 亚洲精品制服丝袜四区| 亚洲一区二区三区夜色| 亚洲an日韩专区在线| 亚洲av日韩综合一区二区三区| 亚洲精品第一国产综合境外资源|