五分鐘學後端技術:如何學習Java工程師必須要會的RPC

来源:https://www.cnblogs.com/xll1025/archive/2020/03/30/12601613.html
-Advertisement-
Play Games

聲明 本文轉自https://developer.51cto.com/art/201906/597963.htm 什麼是RPC RPC(Remote Procedure Call):遠程過程調用,它是一種通過網路從遠程電腦程式上請求服務,而不需要瞭解底層網路技術的思想。 RPC 是一種技術思想而非 ...


聲明

本文轉自https://developer.51cto.com/art/201906/597963.htm

什麼是RPC

RPC(Remote Procedure Call):遠程過程調用,它是一種通過網路從遠程電腦程式上請求服務,而不需要瞭解底層網路技術的思想。

RPC 是一種技術思想而非一種規範或協議,常見 RPC 技術和框架有:

  • 應用級的服務框架:阿裡的 Dubbo/Dubbox、Google gRPC、Spring Boot/Spring Cloud。
  • 遠程通信協議:RMI、Socket、SOAP(HTTP XML)、REST(HTTP JSON)。
  • 通信框架:MINA 和 Netty。

目前流行的開源 RPC 框架還是比較多的,有阿裡巴巴的 Dubbo、Facebook 的 Thrift、Google 的 gRPC、Twitter 的 Finagle 等。

常用的RPC框架

  • gRPC:是 Google 公佈的開源軟體,基於最新的 HTTP 2.0 協議,並支持常見的眾多編程語言。RPC 框架是基於 HTTP 協議實現的,底層使用到了 Netty 框架的支持。
  • Thrift:是 Facebook 的開源 RPC 框架,主要是一個跨語言的服務開發框架。 用戶只要在其之上進行二次開發就行,應用對於底層的 RPC 通訊等都是透明的。不過這個對於用戶來說需要學習特定領域語言這個特性,還是有一定成本的。
  • Dubbo:是阿裡集團開源的一個極為出名的 RPC 框架,在很多互聯網公司和企業應用中廣泛使用。協議和序列化框架都可以插拔是極其鮮明的特色。

完整的 RPC 框架

在一個典型 RPC 的使用場景中,包含了服務發現、負載、容錯、網路傳輸、序列化等組件,其中“RPC 協議”就指明瞭程式如何進行網路傳輸和序列化。

圖 1:完整 RPC 架構圖

如下是 Dubbo 的設計架構圖,分層清晰,功能複雜:

圖 2:Dubbo 架構圖

RPC 核心功能

RPC 的核心功能是指實現一個 RPC 最重要的功能模塊,就是上圖中的”RPC 協議”部分:

圖 3:RPC 核心功能

一個 RPC 的核心功能主要有 5 個部分組成,分別是:客戶端、客戶端 Stub、網路傳輸模塊、服務端 Stub、服務端等。

圖 4:RPC 核心功能圖

下麵分別介紹核心 RPC 框架的重要組成:

  • 客戶端(Client):服務調用方。
  • 客戶端存根(Client Stub):存放服務端地址信息,將客戶端的請求參數數據信息打包成網路消息,再通過網路傳輸發送給服務端。
  • 服務端存根(Server Stub):接收客戶端發送過來的請求消息併進行解包,然後再調用本地服務進行處理。
  • 服務端(Server):服務的真正提供者。
  • Network Service:底層傳輸,可以是 TCP 或 HTTP。

Python 自帶 RPC Demo

Server.py:

fromSimpleXMLRPCServer importSimpleXMLRPCServer

deffun_add(a,b):

totle = a + b

returntotle

if__name__ == '__main__':

s = SimpleXMLRPCServer(( '0.0.0.0', 8080)) #開啟xmlrpcserver

s.register_function(fun_add) #註冊函數fun_add

print"server is online..."

s.serve_forever #開啟迴圈等待

Client.py:

fromxmlrpclib importServerProxy #導入xmlrpclib的包

s = ServerProxy( "http://172.171.5.205:8080") #定義xmlrpc客戶端

prints.fun_add( 2, 3) #調用伺服器端的函數

開啟服務端:

開啟客戶端:

Wireshark 抓包分析過程

客戶端去往服務端:

  • 客戶端 IP:172.171.4.176
  • 服務端 IP:172.171.5.95

通信使用 HTTP 協議,XML 文件傳輸格式。傳輸的欄位包括:方法名 methodName,兩個參數 2,3。

圖 5:Request 抓包

服務端返回結果,欄位返回值 Value,結果是 5:

圖 6:Response 抓包

在這兩次網路傳輸中使用了 HTTP 協議,建立 HTTP 協議之間有 TCP 三次握手,斷開 HTTP 協議時有 TCP 四次揮手。

圖 7:基於 HTTP 協議的 RPC 連接過程

詳細調用過程

Python 自帶 RPC 的 Demo 小程式的實現過程,流程和分工角色可以用下圖來表示:

圖 8:RPC 調用詳細流程圖

一次 RPC 調用流程如下:

  • 服務消費者(Client 客戶端)通過本地調用的方式調用服務。
  • 客戶端存根(Client Stub)接收到調用請求後負責將方法、入參等信息序列化(組裝)成能夠進行網路傳輸的消息體。
  • 客戶端存根(Client Stub)找到遠程的服務地址,並且將消息通過網路發送給服務端。
  • 服務端存根(Server Stub)收到消息後進行解碼(反序列化操作)。
  • 服務端存根(Server Stub)根據解碼結果調用本地的服務進行相關處理
  • 服務端(Server)本地服務業務處理。
  • 處理結果返回給服務端存根(Server Stub)。
  • 服務端存根(Server Stub)序列化結果。
  • 服務端存根(Server Stub)將結果通過網路發送至消費方。
  • 客戶端存根(Client Stub)接收到消息,併進行解碼(反序列化)。
  • 服務消費方得到最終結果。

RPC 核心之功能實現

RPC 的核心功能主要由 5 個模塊組成,如果想要自己實現一個 RPC,最簡單的方式要實現三個技術點,分別是:

  • 服務定址
  • 數據流的序列化和反序列化
  • 網路傳輸

服務定址

服務定址可以使用 Call ID 映射。在本地調用中,函數體是直接通過函數指針來指定的,但是在遠程調用中,函數指針是不行的,因為兩個進程的地址空間是完全不一樣的。

所以在 RPC 中,所有的函數都必須有自己的一個 ID。這個 ID 在所有進程中都是唯一確定的。

客戶端在做遠程過程調用時,必須附上這個 ID。然後我們還需要在客戶端和服務端分別維護一個函數和Call ID的對應表。

當客戶端需要進行遠程調用時,它就查一下這個表,找出相應的 Call ID,然後把它傳給服務端,服務端也通過查表,來確定客戶端需要調用的函數,然後執行相應函數的代碼。

實現方式 服務註冊中心。

要調用服務,首先你需要一個服務註冊中心去查詢對方服務都有哪些實例。Dubbo 的服務註冊中心是可以配置的,官方推薦使用 Zookeeper。

實現案例:
RMI(Remote Method Invocation,遠程方法調用)也就是 RPC 本身的實現方式。

圖 9:RMI 架構圖

Registry(服務發現):
藉助 JNDI 發佈並調用了 RMI服務。實際上,JNDI 就是一個註冊表,服務端將服務對象放入到註冊表中,客戶端從註冊表中獲取服務對象。

RMI 服務在服務端實現之後需要註冊到 RMI Server 上,然後客戶端從指定的 RMI 地址上 Lookup 服務,調用該服務對應的方法即可完成遠程方法調用。

Registry 是個很重要的功能,當服務端開發完服務之後,要對外暴露,如果沒有服務註冊,則客戶端是無從調用的,即使服務端的服務就在那裡。

序列化和反序列化

客戶端怎麼把參數值傳給遠程的函數呢?在本地調用中,我們只需要把參數壓到棧里,然後讓函數自己去棧里讀就行。

但是在遠程過程調用時,客戶端跟服務端是不同的進程,不能通過記憶體來傳遞參數。

這時候就需要客戶端把參數先轉成一個位元組流,傳給服務端後,再把位元組流轉成自己能讀取的格式。

  • 將二進位流轉換成對象的過程叫做反序列化

這個過程叫序列化和反序列化。同理,從服務端返回的值也需要序列化反序列化的過程。

主流序列化協議優缺點對比

JSON

優點
1 簡單易用開發成本低
2 跨語言
3 輕量級數據交換
4 非冗長性(對比xml標簽簡單括弧閉環)

缺點
1 體積大,影響高併發
2 無版本檢查,自己做相容
3 片段的創建和驗證過程比一般的XML複雜
4 缺乏命名空間導致信息混合

總結:最簡單最通用的應用協議,使用廣泛,開發效率高,性能相對較低,維護成本較高。

Protobuf

Protobuf是一種以有效並可擴展的格式編碼結構化數據的方式。

優點
1 跨語言,可自定義數據結構。
2 欄位被編號,新添加的欄位不影響老結構。解決了向後相容問題。
3 自動化生成代碼,簡單易用。
4 二進位消息,效率高,性能高。
5 Netty等框架集成了該協議,提供了編×××提高開發效率。

缺點
1 二進位格式,可讀性差(抓包dump後的數據很難看懂)
2 對象冗餘,欄位很多,生成的類較大,占用空間。
3 預設不具備動態特性(可以通過動態定義生成消息類型或者動態編譯支持)

總結:簡單快速上手,高效相容性強,維護成本較高。

Thrift(Facebook)

優點
1 序列化和RPC支持一站式解決,比pb更方便
2 跨語言,IDL介面定義語言,自動生成多語言文件
3 省流量,體積較小
4 包含完整的客戶端/服務端堆棧,可快速實現RPC
5 為服務端提供了多種工作模式,如線程池模型、非阻塞模型

缺點
1 早期版本問題較大,0.7以前有相容性問題
2 不支持雙通道
3 rpc方法非線程安全,伺服器容易被掛死,需要串列化。
4 預設不具備動態特性(可以通過動態定義生成消息類型或者動態編譯支持)
5 開發環境、編譯較麻煩

總結:跨語言、實現簡單,初次使用較麻煩,需要避免使用問題和場景限制。

image

網路傳輸

網路傳輸:
遠程調用往往用在網路上,客戶端和服務端是通過網路連接的。

所有的數據都需要通過網路傳輸,因此就需要有一個網路傳輸層。網路傳輸層需要把 Call ID 和序列化後的參數位元組流傳給服務端,然後再把序列化後的調用結果傳回客戶端。

只要能完成這兩者的,都可以作為傳輸層使用。因此,它所使用的協議其實是不限的,能完成傳輸就行。

儘管大部分 RPC 框架都使用 TCP 協議,但其實 UDP 也可以,而 gRPC 乾脆就用了 HTTP2。

TCP 的連接是最常見的,簡要分析基於 TCP 的連接:

通常 TCP 連接可以是按需連接(需要調用的時候就先建立連接,調用結束後就立馬斷掉),也可以是長連接(客戶端和伺服器建立起連接之後保持長期持有,不管此時有無數據包的發送,可以配合心跳檢測機制定期檢測建立的連接是否存活有效),多個遠程過程調用共用同一個連接。

所以,要實現一個 RPC 框架,只需要把以下三點實現了就基本完成了:

  • Call ID 映射:可以直接使用函數字元串,也可以使用整數 ID。映射表一般就是一個哈希表。
  • 序列化反序列化:可以自己寫,也可以使用 Protobuf 或者 FlatBuffers 之類的。
  • 網路傳輸庫:可以自己寫 Socket,或者用 Asio,ZeroMQ,Netty 之類。

RPC 核心之網路傳輸協議

在第三節中說明瞭要實現一個 RPC,需要選擇網路傳輸的方式。

圖 10:網路傳輸

在 RPC 中可選的網路傳輸方式有多種,可以選擇 TCP 協議、UDP 協議、HTTP 協議。

每一種協議對整體的性能和效率都有不同的影響,如何選擇一個正確的網路傳輸協議呢?首先要搞明白各種傳輸協議在 RPC 中的工作方式。

基於 TCP 協議的 RPC 調用

由服務的調用方與服務的提供方建立 Socket 連接,並由服務的調用方通過 Socket 將需要調用的介面名稱、方法名稱和參數序列化後傳遞給服務的提供方,服務的提供方反序列化後再利用反射調用相關的方法。

最後將結果返回給服務的調用方,整個基於 TCP 協議的 RPC 調用大致如此。

但是在實例應用中則會進行一系列的封裝,如 RMI 便是在 TCP 協議上傳遞可序列化的 Java 對象。

基於 HTTP 協議的 RPC 調用

該方法更像是訪問網頁一樣,只是它的返回結果更加單一簡單。

其大致流程為:
由服務的調用者向服務的提供者發送請求,這種請求的方式可能是 GET、POST、PUT、DELETE 等中的一種,服務的提供者可能會根據不同的請求方式做出不同的處理,或者某個方法只允許某種請求方式。

而調用的具體方法則是根據 URL 進行方法調用,而方法所需要的參數可能是對服務調用方傳輸過去的 XML 數據或者 JSON 數據解析後的結果,最後返回 JOSN 或者 XML 的數據結果。

由於目前有很多開源的 Web 伺服器,如 Tomcat,所以其實現起來更加容易,就像做 Web 項目一樣。

兩種方式對比

基於 TCP 的協議實現的 RPC 調用,由於 TCP 協議處於協議棧的下層,能夠更加靈活地對協議欄位進行定製,減少網路開銷,提高性能,實現更大的吞吐量和併發數。

但是需要更多關註底層複雜的細節,實現的代價更高。同時對不同平臺,如安卓,iOS 等,需要重新開發出不同的工具包來進行請求發送和相應解析,工作量大,難以快速響應和滿足用戶需求。

基於 HTTP 協議實現的 RPC 則可以使用 JSON 和 XML 格式的請求或響應數據。

而 JSON 和 XML 作為通用的格式標準(使用 HTTP 協議也需要序列化和反序列化,不過這不是該協議下關心的內容,成熟的 Web 程式已經做好了序列化內容),開源的解析工具已經相當成熟,在其上進行二次開發會非常便捷和簡單。

但是由於 HTTP 協議是上層協議,發送包含同等內容的信息,使用 HTTP 協議傳輸所占用的位元組數會比使用 TCP 協議傳輸所占用的位元組數更高。

因此在同等網路下,通過 HTTP 協議傳輸相同內容,效率會比基於 TCP 協議的數據效率要低,信息傳輸所占用的時間也會更長,當然壓縮數據,能夠縮小這一差距。

使用 RabbitMQ 的 RPC 架構

在 OpenStack 中服務與服務之間使用 RESTful API 調用,而在服務內部則使用 RPC 調用各個功能模塊。

正是由於使用了 RPC 來解耦服務內部功能模塊,使得 OpenStack 的服務擁有擴展性強,耦合性低等優點。

OpenStack 的 RPC 架構中,加入了消息隊列 RabbitMQ,這樣做的目的是為了保證 RPC 在消息傳遞過程中的安全性和穩定性。

下麵分析 OpenStack 中使用 RabbitMQ 如何實現 RPC 的調用。

RabbitMQ 簡介

以下摘錄自知乎:

對於初學者,舉一個飯店的例子來解釋這三個分別是什麼吧。不是百分百恰當,但是應該足以解釋這三者的區別。

RPC:
假設你是一個飯店裡的服務員,顧客向你點菜,但是你不會做菜,所以你採集了顧客要點什麼之後告訴後廚去做顧客點的菜,這叫 RPC(remote procedure call),因為廚房的廚師相對於服務員而言是另外一個人(在電腦的世界里就是 Remote 的機器上的一個進程)。廚師做好了的菜就是RPC的返回值。

任務隊列和消息隊列:
本質都是隊列,所以就只舉一個任務隊列的例子。假設這個飯店在高峰期顧客很多,而廚師只有很少的幾個,所以服務員們不得不把單子按下單順序放在廚房的桌子上,供廚師們一個一個做,這一堆單子就是任務隊列,廚師們每做完一個菜,就從桌子上的訂單里再取出一個單子繼續做菜。

角色分擔如下圖:

圖 11:RabbitMQ 在 RPC 中角色

使用 RabbitMQ 的好處:

  • 同步變非同步:可以使用線程池將同步變成非同步,但是缺點是要自己實現線程池,並且強耦合。使用消息隊列可以輕鬆將同步請求變成非同步請求。
  • 低內聚高耦合:解耦,減少強依賴。
  • 流量削峰:通過消息隊列設置請求最大值,超過閥值的拋棄或者轉到錯誤界面。
  • 網路通信性能提高:TCP 的創建和銷毀開銷大,創建 3 次握手,銷毀 4 次分手,高峰時成千上萬條的鏈接會造成資源的巨大浪費,而且操作系統每秒處理 TCP 的數量也是有數量限制的,必定造成性能瓶頸。 RabbitMQ 採用通道通信,不採用 TCP 直接通信。一條線程一條通道,多條線程多條通道,公用一個 TCP 連接。 一條 TCP 連接可以容納無限條通道(硬碟容量足夠的話),不會造成性能瓶頸。

RabbitMQ 的三種類型的交換器

RabbitMQ 使用 Exchange(交換機)和 Queue(隊列)來實現消息隊列。

在 RabbitMQ 中一共有三種交換機類型,每一種交換機類型都有很鮮明的特征。

基於這三種交換機類型,OpenStack 完成兩種 RPC 的調用方式。首先簡單介紹三種交換機。

圖 12:RabbitMQ 架構圖

①廣播式交換器類型(Fanout)

該類交換器不分析所接收到消息中的 Routing Key,預設將消息轉發到所有與該交換器綁定的隊列中去。

圖 13:廣播式交換機

②直接式交換器類型(Direct)

該類交換器需要精確匹配 Routing Key 與 Binding Key,如消息的 Routing Key = Cloud,那麼該條消息只能被轉發至 Binding Key = Cloud 的消息隊列中去。

圖 14:直接式交換機

③主題式交換器(Topic Exchange)

該類交換器通過消息的 Routing Key 與 Binding Key 的模式匹配,將消息轉發至所有符合綁定規則的隊列中。

Binding Key 支持通配符,其中“*”匹配一個片語,“#”匹配多個片語(包括零個)。

圖 15:主題式交換機

註:以上四張圖片來自博客園,如有侵權,請聯繫作者:https://www.cnblogs.com/dwlsxj/p/RabbitMQ.html。

當生產者發送消息 Routing Key=F.C.E 的時候,這時候只滿足 Queue1,所以會被路由到 Queue 中。

如果 Routing Key=A.C.E 這時候會被同時路由到 Queue1 和 Queue2 中,如果 Routing Key=A.F.B 時,這裡只會發送一條消息到 Queue2 中。

Nova 基於 RabbitMQ 實現兩種 RPC 調用:

  • RPC.CALL(調用)
  • RPC.CAST(通知)

其中 RPC.CALL 基於請求與響應方式,RPC.CAST 只是提供單向請求,兩種 RPC 調用方式在 Nova 中均有典型的應用場景。

RPC.CALL

RPC.CALL 是一種雙向通信流程,即 RabbitMQ 接收消息生產者生成的系統請求消息,消息消費者經過處理之後將系統相應結果反饋給調用程式。

圖 16:RPC.CALL 原理圖

一個用戶通過 Dashboard 創建一個虛擬機,界面經過消息封裝後發送給 NOVA-API。

NOVA-API 作為消息生產者,將該消息以 RPC.CALL 方式通過 Topic 交換器轉發至消息隊列。

此時,Nova-Compute 作為消息消費者,接收該信息並通過底層虛擬化軟體執行相應虛擬機的啟動進程。

待用戶虛擬機成功啟動之後,Nova-Compute 作為消息生產者通過 Direct 交換器和響應的消息隊列將虛擬機啟動成功響應消息反饋給 Nova-API。

此時 Nova-API 作為消息消費者接收該消息並通知用戶虛擬機啟動成功。

RPC.CALL 工作原理如下圖:

圖 17:RPC.CALL 具體實現圖

工作流程:

  • 客戶端創建 Message 時指定 reply_to 隊列名、correlation_id 標記調用者。
  • 通過隊列,服務端收到消息。調用函數處理,然後返回。
  • 返回的隊列是 reply_to 指定的隊列,並攜帶 correlation_id。
  • 返回消息到達客戶端,客戶端根據 correlation_id 判斷是哪一個函數的調用返回。

如果有多個線程同時進行遠程方法調用,這時建立在 Client Server 之間的 Socket 連接上會有很多雙方發送的消息傳遞,前後順序也可能是隨機的。

Server 處理完結果後,將結果消息發送給 Client,Client 收到很多消息,怎麼知道哪個消息結果是原先哪個線程調用的?

Client 線程每次通過 Socket 調用一次遠程介面前,生成一個唯一的 ID,即 Request ID(Request ID必需保證在一個 Socket 連接裡面是唯一的),一般常常使用 AtomicLong 從 0 開始累計數字生成唯一 ID。

RPC.CAST

RPC.CAST 的遠程調用流程與 RPC.CALL 類似,只是缺少了系統消息響應流程。

一個 Topic 消息生產者發送系統請求消息到 Topic 交換器,Topic 交換器根據消息的 Routing Key 將消息轉發至共用消息隊列。

與共用消息隊列相連的所有 Topic 消費者接收該系統請求消息,並把它傳遞給響應的服務端進行處理。

其調用流程如圖所示:

圖 18:RPC.CAST 原理圖

連接設計

RabbitMQ 實現的 RPC 對網路的一般設計思路:消費者是長連接,發送者是短連接。但可以自由控制長連接和短連接。

一般消費者是長連接,隨時準備接收處理消息;而且涉及到 RabbitMQ Queues、Exchange 的 auto-deleted 等沒特殊需求沒必要做短連接。發送者可以使用短連接,不會長期占住埠號,節省埠資源。

Nova 中 RPC 代碼設計:

簡單對比 RPC 和 Restful API

RESTful API 架構

REST 最大的幾個特點為:資源、統一介面、URI 和無狀態。

①資源

所謂"資源",就是網路上的一個實體,或者說是網路上的一個具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務,就是一個具體的實在。

②統一介面

RESTful 架構風格規定,數據的元操作,即 CRUD(Create,Read,Update 和 Delete,即數據的增刪查改)操作,分別對應於 HTTP 方法:GET 用來獲取資源,POST 用來新建資源(也可以用於更新資源),PUT 用來更新資源,DELETE 用來刪除資源,這樣就統一了數據操作的介面,僅通過 HTTP 方法,就可以完成對數據的所有增刪查改工作。

③URL

可以用一個 URI(統一資源定位符)指向資源,即每個 URI 都對應一個特定的資源。

要獲取這個資源,訪問它的 URI 就可以,因此 URI 就成了每一個資源的地址或識別符。

④無狀態

所謂無狀態的,即所有的資源,都可以通過 URI 定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而改變。有狀態和無狀態的區別,舉個簡單的例子說明一下。

如查詢員工的工資,如果查詢工資是需要登錄系統,進入查詢工資的頁面,執行相關操作後,獲取工資的多少,則這種情況是有狀態的。

因為查詢工資的每一步操作都依賴於前一步操作,只要前置操作不成功,後續操作就無法執行。

如果輸入一個 URI即可得到指定員工的工資,則這種情況是無狀態的,因為獲取工資不依賴於其他資源或狀態。

且這種情況下,員工工資是一個資源,由一個 URI與之對應,可以通過 HTTP 中的 GET 方法得到資源,這是典型的 RESTful 風格。

RPC 和 Restful API 對比

面對對象不同:

  • RPC 更側重於動作。
  • REST 的主體是資源。

RESTful 是面向資源的設計架構,但在系統中有很多對象不能抽象成資源,比如登錄,修改密碼等而 RPC 可以通過動作去操作資源。所以在操作的全面性上 RPC 大於 RESTful。

傳輸效率:

  • RPC 效率更高。RPC,使用自定義的 TCP 協議,可以讓請求報文體積更小,或者使用 HTTP2 協議,也可以很好的減少報文的體積,提高傳輸效率。

複雜度:

  • RPC 實現複雜,流程繁瑣。
  • REST 調用及測試都很方便。

RPC 實現(參見第一節)需要實現編碼,序列化,網路傳輸等。而 RESTful 不要關註這些,RESTful 實現更簡單。

靈活性:

  • HTTP 相對更規範,更標準,更通用,無論哪種語言都支持 HTTP 協議。
  • RPC 可以實現跨語言調用,但整體靈活性不如 RESTful。

總結

RPC 主要用於公司內部的服務調用,性能消耗低,傳輸效率高,實現複雜。

HTTP 主要用於對外的異構環境,瀏覽器介面調用,App 介面調用,第三方介面調用等。

RPC 使用場景(大型的網站,內部子系統較多、介面非常多的情況下適合使用 RPC):

  • 長鏈接。不必每次通信都要像 HTTP 一樣去 3 次握手,減少了網路開銷。
  • 註冊發佈機制。RPC 框架一般都有註冊中心,有豐富的監控管理;發佈、下線介面、動態擴展等,對調用方來說是無感知、統一化的操作。
  • 安全性,沒有暴露資源操作。
  • 微服務支持。就是最近流行的服務化架構、服務化治理,RPC 框架是一個強力的支撐。

參考文章

https://developer.51cto.com/art/201906/597963.htm

http://www.mamicode.com/info-detail-2443824.html###

博客

Java技術倉庫《Java程式員複習指南》

https://github.com/h2pl/Java-Tutorial

整合全網優質Java學習內容,幫助你從基礎到進階系統化複習Java

面試指南

全網最熱的Java面試指南,共200多頁,非常實用,不管是用於複習還是準備面試都是不錯的。
在公眾號【Java技術江湖】回覆“PDF”即可免費領取。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題目:有1、2、3、4個數字,能組成多少個互不相同且無重覆數字的三位數?都是多少? 程式分析:可填在百位、十位、個位的數字都是1、2、3、4。組成所有的排列後再去 掉不滿足條件的排列。 實例: 1 #include<stdio.h> 2 3 int main() 4 { 5 int i,j,k; 6 ...
  • 前言 眾所周知,maven 實質上是一個插件執行框架,所有的工作都是通過插件完成的。包括我們日常使用到的類似 install、clean、deploy、compiler。。。這些命令,其實底層都是一個一個的 maven 插件。 如何開發自己的插件 1. maven 插件的命名規範 在寫一個項目之前, ...
  • windows10環境下QtCreator中出現skipping incompatible xxx when searching for xxx 我再QtCreator中想導入一個外部庫時,他提示不匹配 出現這種問題是因為QtCreator 和 MinGW 其中一個是32位 ,而另一個是64位, 將 ...
  • 閱讀可能會花上您短短幾分鐘。 大學, 高中沒怎麼花心思讀書,上的是一所三流大學,選擇的電腦專業。 懷著對大學的憧憬,想象著教室里為數不多的馬尾辮,一臺臺電腦前大家熾熱中迸發思考的眼神與鍵盤敲擊聲。 好吧,大家別打了,我說實話還不行嗎,跟大多數同學一樣,基本在混,打游戲,逃課,並寬慰自己大學不經歷這 ...
  • 不足之處,還請海涵,請指出不足。本人發佈過的文章,會不斷更改,力求減少錯誤信息。 Python安裝請借鑒網址https://www.runoob.com/python/python-install.html 安裝註意:(雖然上方鏈接已給出正規(個人認為)安裝過程,但仍有不詳細處。由於本人安裝過一定數 ...
  • 題目:圓圈中最後剩下的數字 0,1,,n-1這n個數字排成一個圓圈,從數字0開始,每次從這個圓圈裡刪除第m個數字。求出這個圓圈裡剩下的最後一個數字。 例如,0、1、2、3、4這5個數字組成一個圓圈,從數字0開始每次刪除第3個數字,則刪除的前4個數字依次是2、0、4、1,因此最後剩下的數字是3。 示例 ...
  • 我的LeetCode:https://leetcode cn.com/u/ituring/ 我的LeetCode刷題源碼[GitHub]:https://github.com/izhoujie/Algorithmcii LeetCode 面試題62. 圓圈中最後剩下的數字 題目 0,1,,n 1這n ...
  • 一核心概念 控制反轉:將bean的生成交給容器,程式可以從容器中獲取指定的bean。 個人理解:此優勢也是spring能夠流行併成為java主流框架的主要原因,java是幫助java程式員以對象的方式管理 記憶體,而spring則是一個管理對象的框架。如果使用spring,在開發中基本上不需要考慮記憶體 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...