日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

當你在構建一個分布式系統時,勢必需要考慮的一個問題是:如何實現服務與服務之間的調用?當然,你可以使用 Dubbo 或 Spring Cloud 等分布式服務框架來封裝技術實現的復雜性,以此完成這個目標。不過,假如現在沒有這些框架,需要你自己來實現遠程調用,你會怎么做呢?

很多人會選擇實現一套 RPC 框架來調用遠程服務。

那么你了解 RPC 架構的基本結構嗎?如果你想要自己實現 RPC 框架來完成遠程調用,又該構建怎么樣的技術體系呢?接下來,我就給你具體介紹一下。

文章首發公眾號:碼猿技術專欄

RPC 架構的基本結構

想要構建一套完整的 RPC 架構,就需要明確該架構所具備的基本結構,而 RPC 架構的基本結構中又存在很多組件。因此接下來,我就通過 RPC 基本結構演進的過程,來給你一一講解下。

首先,我們通常把發生調用關系的兩個服務分別稱為服務的提供者(Provider)和消費者(Consumer)。所以,簡單來說,RPC 就是服務的消費者向提供者發起遠程調用并獲取結果的過程,這是 RPC 最簡單的一種表現形式。

如果想要實現服務提供者和消費者之間的有效交互,那么兩者之間就需要確立與網絡通信相關的網絡協議以及通信通道。同時,服務的提供者需要把自己的服務調用入口暴露出來,并時刻準備接收來自消費者的請求。

這里,我們把通信通道和網絡協議分別命名為 RpcChannel 和 RpcProtocol,而把服務提供者接收請求的組件稱為 RpcAcceptor,把消費者發起請求的組件稱為 RpcConnector。這樣,RPC 架構就演變成了這個樣子:

然后,對于服務提供者和消費者而言,為了雙方能夠正常識別所發送的請求和所接收到的響應結果,需要定義統一的契約。我們把這種契約稱為遠程 API(Remote API),以便與本地 API 加以區別。如此一來,基于同一套遠程 API 的定義,RPC 架構就具備了根據業務來定義通信契約的能力。

類似地,為了更好地區分 RPC 架構中的角色,我們把真正提供業務服務的組件稱為 RpcServer,而把發起真實客戶端請求的組件稱為 RpcClient。這樣,RpcServer 負責實現遠程 API,而 RpcClient 負責調用遠程 API。

當然,對于遠程 API 而言,服務提供者和消費者的處理方式顯然是不一樣的。提供者需要根據消費者的請求來調用 RpcServer 的具體實現并返回結果,這部分的工作由 RpcInvoker 來執行,而消費者通過 RpcCaller 組件對請求進行編碼之后,發送給服務方并等待結果。

最后,為了降低開發人員的開發難度,讓遠程調用的執行過程看上去就像在執行本地方法一樣,在主流的 RPC 實現機制中,通常都會在客戶端添加代理機制,以此提供遠程服務本地化訪問的入口,我們把這個代理組件稱為 RpcProxy。

另外,在服務器端,為了更好地控制業務方法執行過程,通常也會引入具備線程管理、超時控制等機制的 RpcProcessor 組件。

以上就是整個 RPC 架構的演進過程了。從中你可以發現,RPC 架構中的客戶端組件和服務器端組件形成了一種對稱結構,它們各司其職,但又共同構成一個整體。為了幫你加深理解,這里我再總結下前面提到的各個組件。

關注公眾號:碼猿技術專欄,回復關鍵詞:1111 獲取阿里內部JAVA性能調優手冊

客戶端組件與職責包括:

  • RpcClient,負責調用遠程 API,這個過程會依賴于 RpcProxy 提供的代理實現
  • RpcProxy,遠程 API 的代理實現,提供遠程服務本地化訪問的入口
  • RpcCaller,負責編碼和發送調用請求到服務方并等待結果
  • RpcConnector,負責與服務端建立通信通道并發送請求到服務端

服務端組件與職責包括:

  • RpcServer,負責實現遠程 API
  • RpcInvoker,負責調用服務端的具體實現并返回結果
  • RpcProcessor,負責對請求進行處理,高效控制調用過程
  • RpcAcceptor,負責接收客戶方請求并返回請求結果

而客戶端和服務器端所共有的組件包括:

  • RpcProtocol,負責網絡傳輸協議的編碼和解碼
  • RpcChannel,負責建立和維護網絡數據傳輸通道

這樣,我們對一個典型 RPC 架構中的基本結構和組件就有了完整的了解。那么,如果我們想要實現這個架構,需要構建怎樣的技術體系呢?

RPC 架構的技術體系

我們都知道,架構是一種設計上的思想和方法,明白了它的基本結構和組成部分之后,我們就可以進一步梳理想要實現 RPC 架構的技術體系,包括網絡通信、序列化、傳輸協議和遠程調用。

網絡通信

我們先來看網絡通信。網絡通信的涉及面很廣,對于 RPC 架構而言,一方面我們會重點關注性能,所以勢必要考慮基于 TCP 等特定協議的網絡連接方式和 IO 模型;另一方面,我們也需要考慮可靠性,因為這樣才能確保遠程調用過程的穩定。

好,下面我們就具體來看看。

首先是性能問題。一般來說,基于 TCP 協議的網絡連接有兩種基本方式:長連接和短連接。長連接和短連接的本質區別是連接的創建和關閉策略,長連接可以復用現有連接,而短連接則能夠更快地釋放資源。這兩者本身各有利弊,而在 RPC 框架的實現過程中,考慮到性能和服務治理等因素,我們通常是使用長連接進行通信,典型的實現框架就是 Dubbo。

而對于 IO 模型,最簡單、最基礎的網絡 IO 模型就是阻塞式 IO,即 BIO(Blocking IO)。BIO 要求客戶端請求數與服務端線程數一一對應,但是顯然,由于線程的創建需要消耗系統資源,在分布式系統中,服務端可以創建的線程數將會成為系統的瓶頸。

因此,在 RPC 架構中,我們通常都會使用非阻塞 IO,即 NIO(Non-blocking IO)技術來提供性能。基于 NIO 模式下的多路復用機制,創建少數的線程就能對大量請求進行高效的響應。

然后是針對可靠性問題,由于存在網絡閃斷、超時等與網絡狀態相關的不穩定性因素,以及業務系統本身的故障,網絡之間的通信就必須在發生上述問題時能夠快速感知并修復。常見的網絡通信保障手段,包括鏈路有效性檢測及斷線之后的重連處理等。這些機制都比較常見,也不是我們討論的重點,這里就不做具體展開了。

序列化

而如果我們想要在網絡上傳輸數據,就需要用到數據序列化技術了。

目前業界成熟的序列化工具已經有很多,常見的 XML 和 JSON 就是文本類序列化方式的代表,它們可以讓數據以開發人員可讀的方式進行傳輸。還有一種基于二進制實現的方案,包括 google 的 Protocol Buffer 和 Facebook 的 Thrift。

那么,我們在選擇序列化工具時,應該考慮什么呢?一個關鍵指標就是性能。

性能指標主要包括空間復雜度、時間復雜度以及 CPU/ 內存資源占用等。我在下表列舉了目前主流的一些序列化技術,供你參考:

可以看到,在時間維度上,Alibaba 的 fastjson 具有一定優勢;而從空間維度上看,相較其他技術,你可以優先選擇 Protocol Buffer。

傳輸協議

我們知道,但凡涉及通過網絡來傳輸數據,就一定要采用某種傳輸協議。在 ISO/OSI 的 7 層網絡模型中,RPC 架構的設計和實現通常會涉及傳輸層及以上各個層次的相關協議,我們所熟悉的 TCP 協議就屬于傳輸層,而 HTTP 協議則位于應用層。

無論是采用 7 層網絡模型中的哪一層,在網絡請求過程中,數據都是以消息的形式進行傳遞。而消息的組成是有一定結構的,消息頭和消息體構成了所傳輸消息的主體,其中消息體表示需要傳輸的業務數據,而消息頭用于進行傳輸控制。

可以看到,每個層次都從上層取得數據,加上消息頭信息形成新的消息體,并將新的消息傳遞給下一層次。通過對消息頭和消息體進行擴展,我們就可以實現私有化的傳輸協議。

這也是大部分 RPC 框架內部所采用的實現方式,這樣做的主要目的是對公有協議進行精簡,從而提升性能。另外,出于擴展性的考慮,具備高度定制化的私有協議也比公共協議更加容易實現擴展。這方面的典型示例還是 Dubbo 框架,它提供了完全自定義的 Dubbo 協議。

遠程調用

明確了網絡通信的基本方式、序列化手段以及所采用的傳輸協議之后,我們就可以發起真正的遠程調用了。RPC 本質也是一種服務調用,而服務調用存在兩種基本方式,即單向(One Way)模式和請求應答(Request-Response)模式,前者體現為異步操作,后者一般執行同步操作。

首先我們要知道,同步調用會造成業務線程阻塞,但開發和管理會相對簡單。這是為什么呢?我們先來看一下同步調用的時序圖:

從中可以看到,服務線程發送請求到 IO 線程之后,就一直處于等待階段,直到 IO 線程完成與網絡的讀寫操作之后,才會被主動喚醒。

而使用異步調用的目的就在于獲取高性能。在實現異步調用過程中,我們通常都會使用到 Java 中所提供的 Future 機制。Future 調用可以進一步細分成兩種模式,Future-Get 模式和 Future-Listener 模式。Future-Get 模式參考下圖:

可以看到在這種模式下,服務線程通過主動 get 結果的方式獲取 Future 結果,而這個 get 過程是串行的,會造成執行 get 方法的線程形成阻塞。

Future-Listener 模式則不同,在 Future-Listener 模式中需要創建 Listener,當 Future 結果生成時會喚醒注冊到該 Future 上的 Listener 對象,從而形成異步回調機制。

除了同步和異步調用之外,還存在并行(Parallel)調用和泛化(Generic)調用等調用方法,雖然也有其特定的應用場景,但對于 RPC 架構而言并不是主流的調用方式,這里就不具體展開了。

總結

可以說,RPC 是分布式系統中一項基礎設施類的技術體系,但凡涉及服務與服務之間的交互就需要使用到 RPC 架構。當你在使用一個分布式框架時,可以嘗試用今天介紹的 RPC 架構的基本結構和技術體系進行分析,從而加深對這項技術體系的理解。


作者:碼猿技術專欄
鏈接:https://juejin.cn/post/7199456238191116345
來源:稀土掘金
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

分享到:
標簽:架構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定