柚子快報邀請碼778899分享:Dubbo底層原理
柚子快報邀請碼778899分享:Dubbo底層原理
RPC
1、概念
RPC(Remote Procedure Call)叫作遠程過程調(diào)用,它是利用網(wǎng)絡(luò)從遠程計算機上請求服務(wù),可以理解為把程序的一部分放在其他遠程計算機上執(zhí)行(需要有注冊中心)。通過網(wǎng)絡(luò)通信將調(diào)用請求發(fā)送至遠程計算機后,利用遠程計算機的系統(tǒng)資源執(zhí)行這部分程序,最終返回遠程計算機上的執(zhí)行結(jié)果。
2、組成部分
PRC主要設(shè)計五個部分:
user(服務(wù)調(diào)用方)
服務(wù)調(diào)用方也叫服務(wù)消費者,調(diào)用服務(wù)端并獲取返回結(jié)果
user-stub(調(diào)用方的本地存根)
user-stub 負責(zé)將調(diào)用的接口、方法和參數(shù)通過約定的協(xié)議規(guī)范進行編碼并通過本地的 RPCRuntime 實例傳輸?shù)竭h端的實例
RPCRuntime(RPC通信者)
RPCRuntime負責(zé)數(shù)據(jù)包的重傳,數(shù)據(jù)包的確認、數(shù)據(jù)包路由和加密等,在Consumer端和Provider端都會有一個RPCRuntime實例,負責(zé)雙方之間的通信,可靠地將存根船渡地數(shù)據(jù)包傳輸?shù)搅硪欢耍矗汗驳慕涌?/p>
server(服務(wù)端)
服務(wù)提供方就是服務(wù)端,它的職責(zé)就是提供服務(wù),執(zhí)行接口實現(xiàn)的方法邏輯,也就是為服務(wù)提供方的本地存根提供方法的具體實現(xiàn)。
server-stub(服務(wù)端的本地存根)
user-stub 負責(zé)將調(diào)用的接口、方法和參數(shù)通過約定的協(xié)議規(guī)范進行編碼并通過本地的 RPCRuntime 實例傳輸?shù)竭h端的實例
服務(wù)暴露
暴露到遠程:其中的遠程其實是指有一個統(tǒng)一的管理中心來管理所有應(yīng)用服務(wù)的地址和服務(wù)信息,這個統(tǒng)一的管理中心就是注冊中心(Registry)。
3、底層通信協(xié)議
RPC框架與具體的協(xié)議無關(guān)。RPC 可基于 HTTP 或 TCP 協(xié)議,Web Service 就是基于 HTTP 協(xié)議的 RPC,它具有良好的跨平臺性,但其性能卻不如基于 TCP 協(xié)議的 RPC。
(1)TCP/HTTP:眾所周知,TCP 是傳輸層協(xié)議,HTTP 是應(yīng)用層協(xié)議,而傳輸層較應(yīng)用層更加底層,在數(shù)據(jù)傳輸方面,越底層越快,因此,在一般情況下,TCP 一定比 HTTP 快。
(2) 消息ID:RPC 的應(yīng)用場景實質(zhì)是一種可靠的請求應(yīng)答消息流,和 HTTP 類似。因此選擇長連接方式的 TCP 協(xié)議會更高效,與 HTTP 不同的是在協(xié)議層面我們定義了每個消息的唯一 id,因此可以更容易的復(fù)用連接。
(3) IO方式:為了支持高并發(fā),傳統(tǒng)的阻塞式 IO 顯然不太合適,因此我們需要異步的 IO,即 NIO。Java 提供了 NIO 的解決方案,Java 7 也提供了更優(yōu)秀的 NIO.2 支持。
(4) 多連接:既然使用長連接,那么第一個問題是到底 client 和 server 之間需要多少根連接?實際上單連接和多連接在使用上沒有區(qū)別,對于數(shù)據(jù)傳輸量較小的應(yīng)用類型,單連接基本足夠。單連接和多連接最大的區(qū)別在于,每根連接都有自己私有的發(fā)送和接收緩沖區(qū),因此大數(shù)據(jù)量傳輸時分散在不同的連接緩沖區(qū)會得到更好的吞吐效率。所以,如果你的數(shù)據(jù)傳輸量不足以讓單連接的緩沖區(qū)一直處于飽和狀態(tài)的話,那么使用多連接并不會產(chǎn)生任何明顯的提升,反而會增加連接管理的開銷。
(5)心跳:連接是由 client 端發(fā)起建立并維持。如果 client 和 server 之間是直連的,那么連接一般不會中斷(當(dāng)然物理鏈路故障除外)。如果 client 和 server 連接經(jīng)過一些負載中轉(zhuǎn)設(shè)備,有可能連接一段時間不活躍時會被這些中間設(shè)備中斷。為了保持連接有必要定時為每個連接發(fā)送心跳數(shù)據(jù)以維持連接不中斷。心跳消息是 RPC 框架庫使用的內(nèi)部消息,在前文協(xié)議頭結(jié)構(gòu)中也有一個專門的心跳位,就是用來標記心跳消息的,它對業(yè)務(wù)應(yīng)用透明。
4、優(yōu)點
RPC 支持長鏈接,通信不必每次都要像 http 一樣去重復(fù) 3 次握?,減少了網(wǎng)絡(luò)開銷 其次就是 RPC 框架一般都有注冊中心模塊,有完善的監(jiān)控管理功能,服務(wù)注冊發(fā)現(xiàn)、服務(wù)下線、服務(wù)動態(tài)擴展等都方便操作,服務(wù)化治理效率大大提高 基于 TCP 協(xié)議實現(xiàn)的 RPC,能更靈活地對協(xié)議字段進行定制,相比 http 能減少網(wǎng)絡(luò)傳輸字節(jié)數(shù),降低網(wǎng)絡(luò)開銷(握手)提高性能。實現(xiàn)更大的吞吐量和并發(fā)數(shù)
5、應(yīng)用
使用最廣泛的 Spring Cloud、Dubbo,基于 Spring Boot 特性整合了開源行業(yè)中優(yōu)秀的組件,整體對外提供了一套在微服務(wù)架構(gòu)中服務(wù)治理的解決方案。
6、問題
問:服務(wù)啟動的時候服務(wù)基本信息被注冊到注冊中心,如果服務(wù)提供者掛了,注冊中心如何知道服務(wù)不可用了呢?
答:服務(wù)掉線分為主動下線和心跳檢測
主動下線:比如服務(wù)由于發(fā)版時,在重啟之前先主動通知注冊中心:我要重啟了,有流量進來先不要分給我,讓別的機器服務(wù),等我重啟成功后在放流量進來,或者是在管理后臺手動直接摘掉機器,這個是主動下線。
心跳檢測:心跳檢測是處理服務(wù)非正常下線(如斷電斷網(wǎng))的情況,這個時候如果注冊中心不知道該服務(wù)已經(jīng)掉線,一旦被其調(diào)用就會帶來問題。為了避免出現(xiàn)這樣的情況,注冊中心增加一個心跳檢測功能,它會對服務(wù)提供者(Provider)進行心跳檢測,比如每隔 30s 發(fā)送一個心跳,如果三次心跳結(jié)果都沒有返回值,就認為該服務(wù)已下線,趕緊更新 Consumer 的服務(wù)列表,告訴 Consumer 調(diào)用別的機器
問:如果注冊中心掛了,比如你用的是 Zookeeper,如果 Zookeeper 掛了,那服務(wù)之間還能相互調(diào)用嗎?
答:首先注冊中心掛掉也要分兩種情況,如果數(shù)據(jù)庫掛了,ZK 還是能用的,因為 ZK 會緩存注冊機列表在緩存里;
其次 ZK 本身就是一個集群的,一臺機器掛了,ZK 會選舉出集群中的其他機器作為 Master 繼續(xù)提供服務(wù);
如果整個集群都掛了也沒問題,因為調(diào)用者本地會緩存注冊中心獲取的服務(wù)列表。省略和注冊中心的交互,Consumer 和 Provider 采用直連方式,這些策略都是可配置的。
7、RPC 框架實現(xiàn)過程
客戶端 invoke 方法編寫,使用 JDK 的動態(tài)代理技術(shù),客戶端調(diào)用遠程服務(wù)方法時調(diào)用的是 InvocationHandler 的 invoke 方法。 客戶端 Filter 方法編寫,完善的 RPC 框架少不了監(jiān)控、路由、降級、鑒權(quán)等功能。 創(chuàng)建 Socket,在 Filter 方法中實現(xiàn) Client.write 方法,其邏輯為從連接池(ChannelPool)中獲取連接,然后將數(shù)據(jù)寫進 Channel。 實現(xiàn)數(shù)據(jù)序列化、壓縮,目的減少網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)量,向服務(wù)端發(fā)送 request 數(shù)據(jù),這里可以使用 Netty 異步通訊框架。 服務(wù)端收到客戶端發(fā)過的消息后,從 Channel 中將消息讀出來之前,也會先經(jīng)反序列化解壓。 請求就到了服務(wù)端 Filter 中。請求依次經(jīng)過監(jiān)控、鑒權(quán)方法。 根據(jù)客戶端傳遞來的服務(wù)信息和參數(shù),通過反射調(diào)用相應(yīng)的業(yè)務(wù)服務(wù)并拿到業(yè)務(wù)處理結(jié)果。然后在 ResponseFilter 中將返回結(jié)果寫入 Channel。 服務(wù)端序列化、壓縮等,發(fā)送給客戶端。 客戶端收到消息后,經(jīng)過客戶端反序列化、解壓縮,后交給 ResponseThreadPoolProcessor 線程池處理。 ResponseThreadPoolProcessor 收到消息后,就將結(jié)果返回給之前的方法調(diào)用,整個調(diào)用請求就結(jié)束了。
Dubbo
通信原理:Dubbo四大組件
Provider:服務(wù)提供者。 Consumer:服務(wù)消費者。 Registry:服務(wù)注冊與發(fā)現(xiàn)的中心,提供目錄服務(wù),亦稱為服務(wù)注冊中心(如:zookeeper) Monitor:服務(wù)管控中心:對服務(wù)設(shè)置權(quán)限、降級處理,統(tǒng)計服務(wù)的調(diào)用次數(shù)、調(diào)用時間等信息的日志服務(wù)等(如:sentinel)
服務(wù)集成 RPC 后,服務(wù)(這里的服務(wù)就是圖中的 Provider,服務(wù)提供者)啟動后會通過 Register(注冊)模塊,把服務(wù)的唯一 ID 和 IP 地址,端口信息等注冊到 RPC 框架注冊中心(圖中的 Registry 部分)。如springboot集成dubbo后會通過@DubboService注解標注。 當(dāng)調(diào)用者(Consumer)想要調(diào)用服務(wù)的時候,通過 Provider 注冊時的的服務(wù)唯一 ID 去注冊中心查找在線可供調(diào)用的服務(wù),返回一個 IP 列表(3.notify 部分)。如springboot集成dubbo后會通過@DubboReference注解標注。 第三步 Consumer 根據(jù)一定的策略,比如隨機 or 輪訓(xùn)從 Registry 返回的可用 IP 列表真正調(diào)用服務(wù)(4.invoke)。 最后是監(jiān)視功能,RPC 框架都提供監(jiān)控功能,監(jiān)控服務(wù)健康狀況,控制服務(wù)線上擴展和上下線
柚子快報邀請碼778899分享:Dubbo底層原理
精彩文章
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。