91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

RPC的使用場景

發布時間:2020-06-19 14:28:04 來源:億速云 閱讀:1042 作者:元一 欄目:編程語言

概念

RPC采用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,客戶機調用進程發送一個有進程參數的調用信息到服務進程,然后等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息的到達為止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答復信息,然后等待下一個調用信息,最后,客戶端調用進程接收答復信息,獲得進程結果,然后調用執行繼續進行。

完整的RPC框架

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

RPC的使用場景

工作原理

運行時,一次客戶機對服務器的RPC調用,其內部操作大致有如下十步:

1.調用客戶端句柄;執行傳送參數

2.調用本地系統內核發送網絡消息

3.消息傳送到遠程主機

4.服務器句柄得到消息并取得參數

5.執行遠程過程

6.執行的過程將結果返回服務器句柄

7.服務器句柄返回結果,調用遠程系統內核

8.消息傳回本地主機

9.客戶句柄由內核接收消息

10.客戶接收句柄返回的數據

RPC核心功能

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

RPC的使用場景

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

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

一次 RPC 調用流程如下:

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

RPC核心之功能實現

接口調用通常包含兩個部分,序列化和通信協議。常見的序列化協議包括json、xml、hession、protobuf、thrift、text、bytes等;通信比較流行的是http、soap、websockect,RPC通常基于TCP實現。那么restful使用的序列化協議通常是json,通信協議是http;rpc是一種通信協議,因此如果序列化使用json的話,那么就是json-rpc

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

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

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

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

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

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

實現方式:服務注冊中心。

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

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

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

序列化和反序列化

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

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

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

只有二進制數據才能在網絡中傳輸,序列化和反序列化的定義是:

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

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

網絡傳輸

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

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

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

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

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

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

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

RPC 核心之網絡傳輸協議

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

基于 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 的好處:

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

簡單對比 RPC 和 Restful API

REST API的幾個特點為:
  • 資源:就是網絡上的一個實體,或者說是網絡上的一個具體信息。它可以是一段文本、一張圖片、一首歌曲、一種服務,就是一個具體的實在
  • 統一接口:RESTful 架構風格規定,數據的元操作,即 CRUD(Create,Read,Update 和 Delete,即數據的增刪查改)操作,分別對應于 HTTP 方法:GET 用來獲取資源,POST 用來新建資源(也可以用于更新資源),PUT 用來更新資源,DELETE 用來刪除資源,這樣就統一了數據操作的接口,僅通過 HTTP 方法,就可以完成對數據的所有增刪查改工作。
  • URL:可以用一個 URI(統一資源定位符)指向資源,即每個 URI 都對應一個特定的資源。
    要獲取這個資源,訪問它的 URI 就可以,因此 URI 就成了每一個資源的地址或識別符
  • 無狀態:所謂無狀態的,即所有的資源,都可以通過 URI 定位,而且這個定位與其他資源無關,也不會因為其他資源的變化而改變
RPC 和 Restful API 對比
  • 面對對象不同:RPC 更側重于動作,REST 的主體是資源
  • 傳輸效率:RPC 效率更高。RPC,使用自定義的 TCP 協議,可以讓請求報文體積更小,或者使用 HTTP2 協議,也可以很好的減少報文的體積,提高傳輸效率
  • 復雜度:RPC 實現復雜,流程繁瑣,REST 調用及測試都很方便
  • 靈活性:HTTP 相對更規范,更標準,更通用,無論哪種語言都支持 HTTP 協議;RPC 可以實現跨語言調用,但整體靈活性不如 RESTful

總結

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

RESTful API 主要用于對外的異構環境,瀏覽器接口調用,App 接口調用,第三方接口調用等

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

  • 長鏈接。不必每次通信都要像 HTTP 一樣去 3 次握手,減少了網絡開銷。
  • 注冊發布機制。RPC 框架一般都有注冊中心,有豐富的監控管理;發布、下線接口、動態擴展等,對調用方來說是無感知、統一化的操作。
  • 安全性,沒有暴露資源操作。
  • 微服務支持。就是最近流行的服務化架構、服務化治理,RPC 框架是一個強力的支撐。
向AI問一下細節
推薦閱讀:
  1. RPC是什么?
  2. Hadoop的RPC

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

吐鲁番市| 石渠县| 临沧市| 巴彦淖尔市| 莱芜市| 安顺市| 泊头市| 阆中市| 玛沁县| 酉阳| 岗巴县| 印江| 凉城县| 涞源县| 凭祥市| 应城市| 肃宁县| 东台市| 台南县| 达日县| 安阳县| 漳州市| 桂阳县| 即墨市| 大同县| 嘉峪关市| 格尔木市| 千阳县| 桂阳县| 乐至县| 田林县| 麻阳| 洪洞县| 嘉鱼县| 宣化县| 抚宁县| 麻阳| 云浮市| 罗城| 法库县| 静宁县|