當前位置:編程學習大全網 - 編程語言 - 從 0 到 1:全面理解 RPC 遠程調用

從 0 到 1:全面理解 RPC 遠程調用

作者 | Python編程時光

責編 | 胡巍巍

什麽是RPC呢?百度百科給出的解釋是這樣的:“RPC(Remote Procedure Call Protocol)——遠程過程調用協議,它是壹種通過網絡從遠程計算機程序上請求服務,而不需要了解底層網絡技術的協議”。

這個概念聽起來還是比較抽象,沒關系,繼續往後看,後面概念性的東西,我會講得足夠清楚,讓妳完全掌握 RPC 的基礎內容。

在 OpenStack 裏的進程間通信方式主要有兩種,壹種是基於HTTP協議的RESTFul API方式,另壹種則是RPC調用。

那麽這兩種方式在應用場景上有何區別呢?

有使用經驗的人,就會知道:

首先,給妳提兩個問題,帶著這兩個問題再往下看:

1、RPC 和 REST 區別是什麽?2、為什麽要采用RPC呢?

首先,第壹個問題:RPC 和 REST 區別是什麽?

妳壹定會覺得這個問題很奇怪,是的,包括我,但是妳在網絡上壹搜,會發現類似對比的文章比比皆是,我在想可能很多初學者由於基礎不牢固,才會將不相幹的二者拿出來對比吧。既然是這樣,那為了讓妳更加了解陌生的RPC,就從妳熟悉得不能再熟悉的 REST 入手吧。

01、所屬類別不同

REST,是Representational State Transfer 的簡寫,中文描述表述性狀態傳遞(是指某個瞬間狀態的資源數據的快照,包括資源數據的內容、表述格式(XML、JSON)等信息。)

REST 是壹種軟件架構風格。這種風格的典型應用,就是HTTP。其因為簡單、擴展性強的特點而廣受開發者的青睞。

而RPC 呢,是 Remote Procedure Call Protocol 的簡寫,中文描述是遠程過程調用,它可以實現客戶端像調用本地服務(方法)壹樣調用服務器的服務(方法)。

而 RPC 可以基於 TCP/UDP,也可以基於 HTTP 協議進行傳輸的,按理說它和REST不是壹個層面意義上的東西,不應該放在壹起討論,但是誰讓REST這麽流行呢,它是目前最流行的壹套互聯網應用程序的API設計標準,某種意義下,我們說 REST 可以其實就是指代 HTTP 協議。

02、使用方式不同

03、面向對象不同

從設計上來看,RPC,所謂的遠程過程調用 ,是面向方法的 ,REST:所謂的 Representational state transfer ,是面向資源的,除此之外,還有壹種叫做 SOA,所謂的面向服務的架構,它是面向消息的,這個接觸不多,就不多說了。

04、序列化協議不同

接口調用通常包含兩個部分,序列化和通信協議。

通信協議,上面已經提及了,REST 是 基於 HTTP 協議,而 RPC 可以基於 TCP/UDP,也可以基於 HTTP 協議進行傳輸的。

常見的序列化協議,有:json、xml、hession、protobuf、thrift、text、bytes等,REST 通常使用的是 JSON或者XML,而 RPC 使用的是 JSON-RPC,或者 XML-RPC。

通過以上幾點,我們知道了 REST 和 RPC 之間有很明顯的差異。

然後第二個問題:為什麽要采用RPC呢?

那到底為何要使用 RPC,單純的依靠RESTful API不可以嗎?為什麽要搞這麽多復雜的協議,渣渣表示真的學不過來了。

關於這壹點,以下幾點僅是我的個人猜想,僅供交流哈:

說了這麽多,我們該如何選擇這兩者呢?我總結了如下兩點,供妳參考:

“遠程調用”意思就是:被調用方法的具體實現不在程序運行本地,而是在別的某個地方(分布到各個服務器),調用者只想要函數運算的結果,卻不需要實現函數的具體細節。

光說不練嘴把式,接下來,我將分別用三種不同的方式全面地讓妳搞明白 rpc 遠程調用是如何實現的。

01、基於 xml-rpc

Python實現 rpc,可以使用標準庫裏的 SimpleXMLRPCServer,它是基於XML-RPC 協議的。

有了這個模塊,開啟壹個 rpc server,就變得相當簡單了。執行以下代碼:

有了 rpc server,接下來就是 rpc client,由於我們上面使用的是 XML-RPC,所以 rpc clinet 需要使用xmlrpclib 這個庫。

然後,我們通過 server_proxy 對象就可以遠程調用之前的rpc server的函數了。

SimpleXMLRPCServer是壹個單線程的服務器。這意味著,如果幾個客戶端同時發出多個請求,其它的請求就必須等待第壹個請求完成以後才能繼續。

若非要使用 SimpleXMLRPCServer 實現多線程並發,其實也不難。只要將代碼改成如下即可。

02、基於json-rpc

SimpleXMLRPCServer 是基於 xml-rpc 實現的遠程調用,上面我們也提到 除了 xml-rpc 之外,還有 json-rpc 協議。

那 python 如何實現基於 json-rpc 協議呢?

答案是很多,很多web框架其自身都自己實現了json-rpc,但我們要獨立這些框架之外,要尋求壹種較為幹凈的解決方案,我查找到的選擇有兩種

第壹種是 jsonrpclib

第二種是 python-jsonrpc

先來看第壹種 jsonrpclib

它與 Python 標準庫的 SimpleXMLRPCServer 很類似(因為它的類名就叫做 SimpleJSONRPCServer ,不明真相的人真以為它們是親兄弟)。或許可以說,jsonrpclib 就是仿照 SimpleXMLRPCServer 標準庫來進行編寫的。

它的導入與 SimpleXMLRPCServer 略有不同,因為SimpleJSONRPCServer分布在jsonrpclib庫中。

服務端

客戶端

再來看第二種python-jsonrpc,寫起來貌似有些復雜。

服務端

客戶端

調用過程如下

還記得上面我提到過的 zabbix API,因為我有接觸過,所以也拎出來講講。zabbix API 也是基於 json-rpc 2.0協議實現的。

因為內容較多,這裏只帶大家打個,zabbix 是如何調用的:直接指明要調用 zabbix server 的哪個方法,要傳給這個方法的參數有哪些。

03、基於 zerorpc

以上介紹的兩種rpc遠程調用方式,如果妳足夠細心,可以發現他們都是) ,我會更新補充 notify 的內容。

OpenStack RPC 模塊提供了 rpc.call,rpc.cast, rpc.fanout_cast 三種 RPC 調用方法,發送和接收 RPC 請求。

rpc.call 和 .rpc.cast 從實現代碼上看,他們的區別很小,就是call調用時候會帶有wait_for_reply=True參數,而cast不帶。

要了解 rpc 的調用機制呢,首先要知道 oslo_messaging 的幾個概念主要方法有四個:

transport:RPC功能的底層實現方法,這裏是rabbitmq的消息隊列的訪問路徑

transport 就是定義妳如何訪連接消息中間件,比如妳使用的是 Rabbitmq,那在 nova.conf中應該有壹行transport_url的配置,可以很清楚地看出指定了 rabbitmq 為消息中間件,並配置了連接rabbitmq的user,passwd,主機,端口。

target用來表述 RPC 服務器監聽topic,server名稱和server監聽的exchange,是否廣播fanout。

rpc server 要獲取消息,需要定義target,就像壹個門牌號壹樣。

rpc client 要發送消息,也需要有target,說明消息要發到哪去。

endpoints:是可供別人遠程調用的對象

RPC服務器暴露出endpoint,每個 endpoint 包涵壹系列的可被遠程客戶端通過 transport 調用的方法。直觀理解,可以參考nova-conductor創建rpc server的代碼,這邊的endpoints就是 nova/manager.py:ConductorManager

dispatcher:分發器,這是 rpc server 才有的概念

只有通過它 server 端才知道接收到的rpc請求,要交給誰處理,怎麽處理?

在client端,是這樣指定要調用哪個方法的。

而在server端,是如何知道要執行這個方法的呢?這就是dispatcher 要幹的事,它從 endpoint 裏找到這個方法,然後執行,最後返回。

Serializer:在 python 對象和message(notification) 之間數據做序列化或是反序列化的基類。

主要方法有四個:

每個notification listener都和壹個executor綁定,來控制收到的notification如何分配。默認情況下,使用的是blocking executor(具體特性參加executor壹節)

模仿是壹種很高效的學習方法,我這裏根據 OpenStack 的調用方式,抽取出核心內容,寫成壹個簡單的 demo,有對 OpenStack 感興趣的可以了解壹下,大部分人也可以直接跳過這章節。

註意以下代碼不能直接運行,妳還需要配置 rabbitmq 的連接方式,妳可以寫在配置文件中,通過 get_transport 從cfg.CONF 中讀取,也可以直接將其寫成url的格式做成參數,傳給 get_transport 。而且還要nova或者其他openstack組件的環境中運行(因為需要有ctxt這個環境變量)

簡單的 rpc client

簡單的 rpc server

End

熱 文 推 薦

?Facebook 發幣 Libra;谷歌十億美金為窮人造房;第四代樹莓派 Raspberry Pi 4 發布 | 開發者周刊

?WebRTC 將壹統實時音視頻天下?

?小米崔寶秋:小米 AIoT 深度擁抱開源

?華為在美研發機構 Futurewei 意欲分家?

?老司機教妳如何寫出沒人敢維護的代碼!

?Python有哪些技術上的優點?比其他語言好在哪兒?

?上不了北大“圖靈”、清華“姚班”,AI專業還能去哪上?

?公鏈史記 | 從鴻蒙初辟到萬物生長的十年激蕩……

?邊緣計算容器化是否有必要?

?馬雲曾經偶像,終於把阿裏留下的1400億敗光了!

妳點的每個“在看”,我都認真當成了喜歡

  • 上一篇:什麽是壓力容器
  • 下一篇:嵌入式學習入門書籍有哪些
  • copyright 2024編程學習大全網