RPC在Python中的使用及原理浅析
RPC是遠程過程調用(Remote Procedure Call)的縮寫形式。RPC采用客戶機/服務器模式。請求程序就是一個客戶機,而服務提供程序就是一個服務器。首先,調用進程發送一個有進程參數的調用信息到服務進程,然后等待應答信息。在服務器端,進程保持睡眠狀態直到調用信息的到達為止。當一個調用信息到達,服務器獲得進程參數,計算結果,發送答復信息,然后等待下一個調用信息,最后,客戶端調用過程接收答復信息,獲得進程結果,然后調用執行繼續進行。
gRPC 是Google開源的一款高性能 RPC 框架,基于 ProtoBuf 序列化協議進行開發,支持多種語言。下面介紹Python語言的gRPC通信示例。
1 python3使用gRPC示例
使用案例:小寫字符串轉換為大寫字符串。目錄結構如下:
1.1 安裝 Python 依賴包
pip install protobuf pip install grpcio pip install grpcio-tools1.2 新建 data.proto文件
data.proto 為protobuf格式文件,定義了數據類以及遠程調用方法。
syntax = "proto3"; package base_package;service FormatData { //定義服務,用在rpc傳輸中rpc DoFormat(actionrequest) returns (actionresponse){} }message actionrequest {string text = 1; }message actionresponse{string text=1; }1.3 生成proto數據的python調用格式、gRPC方法接口
在Linux平臺中運行:
python -m grpc_tools.protoc -I. --python_out=./base_package --grpc_python_out=./base_package ./data.proto在 base_package 文件夾下生成 data_pb2.py 和 data_pb2_grpc.py,其中 data_pb2.py 為數據格式文件,data_pb2_grpc.py 為gRPC方法文件。
1.4 gRPC服務端
服務端具體實現了proto文件中定義的方法 DoFormat,將實現后的服務類添加到gRPC服務端中,當服務端接收到客戶端要調用的函數名時通過反射機制執行具體的方法并返回執行結果。
import grpc import time from concurrent import futures from base_package import data_pb2, data_pb2_grpc_ONE_DAY_IN_SECONDS = 60 * 60 * 24 _HOST = 'localhost' _PORT = '8080'class FormatData(data_pb2_grpc.FormatDataServicer):# 重寫接口函數def DoFormat(self, request, context):str = request.textreturn data_pb2.actionresponse(text=str.upper()) # 返回一個類實例def server():# 定義服務器并設置最大連接數,corcurrent.futures是一個并發庫,類似于線程池的概念grpcServer = grpc.server(futures.ThreadPoolExecutor(max_workers=4)) # 創建一個服務器data_pb2_grpc.add_FormatDataServicer_to_server(FormatData(), grpcServer) # 在服務器中添加派生的接口服務(自己實現了處理函數)grpcServer.add_insecure_port(_HOST + ':' + _PORT) # 添加監聽端口grpcServer.start() # 啟動服務器try:while True:time.sleep(_ONE_DAY_IN_SECONDS)except KeyboardInterrupt:grpcServer.stop(0) # 關閉服務器if __name__ == '__main__':server()1.5 gRPC客戶端
客戶端連接gRPC服務端后,即可進行遠程過程調用。
import grpc from base_package import data_pb2, data_pb2_grpc_HOST = 'localhost' _PORT = '8080'def run():conn = grpc.insecure_channel(_HOST + ':' + _PORT) # 監聽頻道client = data_pb2_grpc.FormatDataStub(channel=conn) # 客戶端使用Stub類發送請求,參數為頻道,為了綁定鏈接response = client.DoFormat(data_pb2.actionrequest(text='hello,world!')) # 返回的結果就是proto中定義的類print("received: " + response.text)if __name__ == '__main__':run()輸出結果:
received: HELLO,WORLD!2 RPC基本原理淺析
2.1 RPC架構
一個完整的RPC架構里面包含了四個核心的組件,分別是Client,Client Stub,Server以及Server Stub,這個Stub可以理解為存根。
- 客戶端(Client),服務的調用方。
- 客戶端存根(Client Stub),負責RPC調用的請求編碼和響應結果解碼,即把調用涉及到的方法、調用參數等按照Client端和Server端約定的協議編碼發送到Server端,接收Server的響應并對響應進行解碼從而得到最終的RPC調用結果。
- 服務端(Server),真正的服務提供者。
- 服務端存根(Server Stub),接受Client端發送的調用請求,并按照Client端和Server端約定的遠程調用協議對請求進行解碼,根據解碼后的請求定位到Server端被調用的目標代碼,調用處理完之后對返回結果進行編碼發送到Client端。
2.2 RPC流程
(1) 客戶端(client)以本地調用方式(即以接口的方式)調用服務;
(2) 客戶端存根(client stub)接收到調用后,負責將方法、參數等組裝成能夠進行網絡傳輸的消息體(將消息體對象序列化為二進制);
(3) 客戶端通過sockets將消息發送到服務端;
(4) 服務端存根( server stub)收到消息后進行解碼(將消息對象反序列化);
(5) 服務端存根( server stub)根據解碼結果調用本地的服務;
(6) 本地服務執行并將結果返回給服務端存根( server stub);
(7) 服務端存根( server stub)將返回結果打包成消息(將結果消息對象序列化);
(8) 服務端(server)通過sockets將消息發送到客戶端;
(9) 客戶端存根(client stub)接收到結果消息,并進行解碼(將結果消息反序列化);
(10) 客戶端(client)得到最終結果。
RPC的目標是要把2、3、4、7、8、9這些步驟都封裝起來。
2.3 RPC作用及優勢
作用
- 1、使服務解耦
- 2、分布式設計
- 3、部署靈活
- 4、容易擴展
優勢
1、一般使用長鏈接,不必每次通信都要3次握手,減少網絡開銷
2、一般都有注冊中心,有豐富的監控管理
3、發布、下線接口、動態擴展等,對調用方來說是無感知、統一化的操作
4、協議私密,安全性較高
5、rpc 能做到協議更簡單內容更小,效率更高
6、rpc 是面向服務的更高級的抽象,支持服務注冊發現,負載均衡,超時重試,熔斷降級等高級特性。
3 RPC 和 HTTP 的區別及適用場景
3.1 RPC 和 HTTP 區別
1、傳輸協議:
RPC:可以基于HTTP協議,也可以基于TCP協議
HTTP:基于HTTP協議
從網絡協議來說,Http協議與Rpc同屬于應用層, 他們的底層都是tcp協議。RPC和HTTP他們最本質的區別,就是RPC主要工作在TCP協議之上,而HTTP服務主要是工作在HTTP協議之上,我們都知道HTTP協議是在傳輸層協議TCP之上的,所以效率來看的話,RPC當然是要更勝一籌。
2、傳輸效率:
RPC:使用自定義的TCP協議,可以讓請求報文體積更小,或者使用HTTP2協議,也可以很好的減小報文體積,提高傳輸效率
HTTP:如果是基于http1.1的協議,請求中會包含很多無用的內容,如果是基于HTTP2.0,那么簡單的封裝下可以作為一個RPC來使用,這時標準的RPC框架更多的是服務治理。
http協議其實是屬于面向桌面瀏覽器的一個通信協議,對于緩存,冪等或者Cookies相關的方面做了很多的事情。但是對于服務器之間直接的交互,Rpc就能夠體現出來他的優勢了。自定義協議,減少數據傳輸:我們大概看一下http協議。請求行,請求頭部,請求數據,空行。很明顯對于遠程調用場景,我們對于請求行的依賴不是特別的強,那么這一部分在我們應用場景下,將會成為負擔,但是http協議又是固定的,我們也不可能隨便修改協議的格式。所以,通過rpc協議我們可以精簡請求的數據,來盡可能少的傳輸我們的數據。當前,rpc也可以通過http協議來進行傳輸。
3、性能消耗:
RPC:可以基于protobuf實現高效的二進制傳輸
HTTP:大部分是基于json實現的,字節大小和序列化耗時都比protobuf要更消耗性能。
4、負載均衡:
RPC:基本自帶了負載均衡策略
HTTP:需要配置Nginx、HAProxy配置
5、服務治理:(下游服務新增,重啟,下線時如何不影響上游調用者)
RPC:能做到自動通知,不影響上游
HTTP:需要事先通知,如修改NGINX配置。
6、連接:
RPC:長連接
HTTP:短連接
rpc使用長連接:直接基于socket進行連接,不用每個請求都重新走三次握手的流程。
3.2 使用場景
RPC服務一般用于集群內部微服務之間的通信,如果需要對外暴露服務一般會提供等價的HTTP REST接口。
參考
Python語言實現gRPC通信 (在Linux環境下生成proto文件!在windows下面執行錯誤了)
RPC原理解析
Python——gRPC詳解及實戰避坑方案(上)
什么是RPC
http與rpc對比
總結
以上是生活随笔為你收集整理的RPC在Python中的使用及原理浅析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: AngularJs的一些知识点-1
- 下一篇: 开源协议。