gRPC 使用(python 版本)

.proto 文件

.proto 文件gRPC 和 Protocol Buffers 的接口定義文件,它描述了:

  1. 要傳遞什么數據(也就是消息體 message)。
  2. 要暴露什么接口(也就是服務 service 和它們的 方法)。

也就是一份規范文件,讓客戶端和服務端能按照相同的約定相互通信。

my_service.proto

syntax = "proto3";  // 指定使用 proto3 語法版本package demo;       // 包名,方便生成代碼時分模塊service MyService {// 定義 RPC 服務rpc Predict(PredictRequest) returns (PredictResponse) {}
}message PredictRequest {string prompt = 1;
}message PredictResponse {string result = 1;
}
  1. 用 protoc 自動生成客戶端/服務端代碼
    這里使用 python 來進行操作
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. my_service.proto
  • I. 指定 proto 搜索路徑為當前目錄
  • -python_out=. 生成 my_service_pb2.py(定義消息類型)
  • -grpc_python_out=. 生成 my_service_pb2_grpc.py(定義服務類接口)

因為 gRPC 要跨語言,所以必須有語言無關的描述文件

  • .proto 就是統一規范

  • Protocol Buffers 定義數據傳輸結構(比 JSON 輕量、高速、強類型)

  • gRPC 框架用它生成客戶端/服務端、自動序列化、自動網絡傳輸

  • protoc 會以輸入文件 my_service.proto 的文件名為基準自動生成對應的 Python 文件。

  • 它沒有單獨的參數去自定義生成文件名,所以默認就是:

    ? my_service_pb2.py:

    • 包含你 .proto 中定義的 message 和 enum 類型對應的 Python 類。

    ? my_service_pb2_grpc.py:

    • 包含你 .proto 中定義的 service 和 RPC 方法對應的客戶端和服務端樁代碼。
<proto文件名>_pb2.py
<proto文件名>_pb2_grpc.py
文件包含內容用途
my_service_pb2.py消息類型類(message、enum)序列化/反序列化數據
my_service_pb2_grpc.py服務類和客戶端/服務端接口實現服務邏輯/調用遠程服務
  • pb2.py → 負責數據模型
  • pb2_grpc.py → 負責服務調用邏輯(RPC 接口)

服務端實現

from concurrent import futures
import grpc
import my_service_pb2
import my_service_pb2_grpc# 實現 RPC 服務
class MyService(my_service_pb2_grpc.MyServiceServicer):
# 是生成的服務端基類,這里我們繼承它并實現 Predict 方法邏輯。def Predict(self, request, context):print(f"Received prompt: {request.prompt}")return my_service_pb2.PredictResponse(result=f"Hello, {request.prompt}!")# 啟動 gRPC 服務器
def serve():server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))my_service_pb2_grpc.add_MyServiceServicer_to_server(MyService(), server)server.add_insecure_port("[::]:50051")server.start()print("gRPC Server running at 0.0.0.0:50051...")server.wait_for_termination()if __name__ == "__main__":serve()#  python -m grpc_tools.protoc -I. --pytheon_out=. --grpc_python_out=. my_service.proto

? grpc.server(…) 創建 gRPC 服務器實例,并給它分配一個線程池(能同時處理多個請求)。

? add_MyServiceServicer_to_server(MyService(), server) 注冊我們自己實現的服務邏輯。

? server.add_insecure_port(“[::]:50051”) 打開監聽端口。

? server.start() 啟動服務,wait_for_termination() 讓服務持續監聽,不會自動結束。

_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'my_service_pb2', _globals)

  • 動態注冊生成消息類

也就是:

  • PredictRequest、PredictResponse 這些類在導入時動態創建,IDE 靜態分析器(比如 PyCharm)無法提前知道它們存在,因此你用 IDE 查看時找不到定義。
  • 但是程序運行時,這些類會存在,并能正常使用。
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10my_service.proto\x12\x04\x64\x65mo\" \n\x0ePredictRequest\x12\x0e\n\x06prompt\x18\x01 \x01(\t\"!\n\x0fPredictResponse\x12\x0e\n\x06result\x18\x01 \x01(\t2E\n\tMyService\x12\x38\n\x07Predict\x12\x14.demo.PredictRequest\x1a\x15.demo.PredictResponse\"\x00\x62\x06proto3')
  • AddSerializedFile(…) 把你 .proto 定義編譯成的二進制描述數據注冊進 DescriptorPool。
  • 也就是把整個 my_service.proto 的結構信息(服務、消息類型、字段等)塞入一個描述池中。

客戶端實現

import grpc
import my_service_pb2
import my_service_pb2_grpcdef run_client():channel = grpc.insecure_channel("localhost:50051")stub = my_service_pb2_grpc.MyServiceStub(channel)response = stub.Predict(my_service_pb2.PredictRequest(prompt="World111"))print(f"Server response: {response.result}")if __name__ == "__main__":run_client()

客戶端主要做三件事:

  1. 建立 gRPC 連接(channel)。
  2. 使用自動生成的 stub 來調用服務端方法。
  3. 接收服務端返回的響應并打印。
代碼部分解釋
grpc.insecure_channel()使用未加密通道(適合本地測試,不推薦生產環境直接用這個,要用 TLS 版 secure_channel())
MyServiceStub(channel)這是 gRPC 自動生成的客戶端類,內部已經幫你實現好了 RPC 序列化、反序列化邏輯
PredictRequest()使用自動生成的類構造 RPC 請求對象,這個類對應你的 proto 中定義的消息類型
stub.Predict(…)相當于遠程調用服務端的 Predict(),gRPC 會自動序列化請求、網絡傳輸、反序列化響應
response.result服務端返回的 PredictResponse 消息對象,取它的 result 字段就是你服務返回的內容

🚀 客戶端 vs 服務端對應關系

服務端:

class MyService(my_service_pb2_grpc.MyServiceServicer):def Predict(self, request, context):return my_service_pb2.PredictResponse(result=f"Hello, {request.prompt}!")

客戶端:

response = stub.Predict(my_service_pb2.PredictRequest(prompt="World111")
)

客戶端調用 Predict() 時:

  • 底層幫你序列化 prompt 參數并傳給服務端
  • 服務端執行對應邏輯并返回 result 給客戶端
  • 客戶端拿到結果打印出來 🎉

也可以使用 go 來客戶端,注意先

protoc --go_out=. --go-grpc_out=. my_service.proto

go

package mainimport ("context""log""time""google.golang.org/grpc"pb "path/to/generated/my_service" // 引入生成的包
)func main() {// 1?? 建立 gRPC 連接conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err != nil {log.Fatalf("連接失敗: %v", err)}defer conn.Close()// 2?? 創建客戶端存根client := pb.NewMyServiceClient(conn)// 3?? 調用服務ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)defer cancel()resp, err := client.Predict(ctx, &pb.PredictRequest{Prompt: "Hello Go!"})if err != nil {log.Fatalf("調用錯誤: %v", err)}log.Printf("服務返回: %s\n", resp.Result)
}

總結

無論是 gRPC、騰訊的 tRPC,甚至國內很多 RPC 框架(例如阿里 HSF、螞蟻 SOFA RPC),它們背后的實現思路都是一樣的👇:

🔄共同點:

  1. 先定義接口協議(IDL)

    用 proto、.thrift、.proto3 或者類似 IDL 文件描述你的服務、方法、消息。

  2. 代碼生成器生成對應語言的客戶端/服務端存根

    protoc、trpcproto 或者對應語言插件 → 自動生成:

    • 服務接口類(Stub / Service 接口)
    • 消息類(序列化 / 反序列化邏輯)
  3. 服務端實現 Service 類邏輯

    你只需繼承生成的服務接口,然后實現方法邏輯即可。

  4. 客戶端用生成的存根調用方法

    就像調用本地函數一樣,不需要手動拼接網絡數據、序列化二進制流。

.proto 文件↓
[生成工具] 自動生成代碼↓
服務端: 實現 Service 類
客戶端: 使用 Client Stub 調用↓
底層負責網絡傳輸、序列化、負載均衡、錯誤處理...

? 減少重復代碼 — 不用你手寫網絡序列化部分

? 強類型檢查 — 調用方/服務方都能知道數據結構

? 方便跨語言調用 — 一份協議,不同語言都能生成對應客戶端、服務端

? 減少網絡細節關注 — 把網絡部分封裝起來

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/88576.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/88576.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/88576.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

VMware安裝

勾選【增強型鍵盤驅動程序】 #后期虛擬機用鼠標鍵盤比較好用 VMware創建主機Windows2 選擇類型配置【自定義】 安裝客戶機操作系統【稍后安裝操作系統】 客戶機操作系統【Microsoft Windows】,版本選Windows最高版本 【固件類型】默認UEFI 【處理器配置】選1個處理…

【沉浸式解決問題】微服務子模塊引入公共模塊的依賴后無法bean未注入

目錄 一、問題描述二、場景還原三、原因分析四、解決方案五、拓展知識參考文獻 一、問題描述 在微服務項目中的公共模塊進行了Mybatis Plus配置&#xff0c;創建了配置類并添加了Configuration注解&#xff0c;其他模塊引入該模塊后不生效 我這里是在Mybatis Plus公共模塊中注…

SQL進階:CASE表達式

目錄 1、用一條SQL語句進行不同條件的統計 建表語句&#xff08;MySQL8&#xff09;&#xff1a; 錄入數據&#xff1a; *按性別統計SQL 輸出結果&#xff08;行列轉換&#xff09; 2、在UPDATE語句里進行條件分支 建表語句&#xff08;MySQL8&#xff09;&#xff1a;…

哪四款AI工具讓3D人物手辦制作如此簡單?

在當今數字化時代&#xff0c;AI技術的飛速發展為我們的生活帶來了諸多便利和驚喜。其中&#xff0c;AI生成3D人物手辦工具的出現&#xff0c;讓我們能夠輕松地將自己的創意和想象轉化為實體手辦&#xff0c;滿足了眾多手辦愛好者的個性化需求。今天&#xff0c;我將為大家推薦…

Docker高級管理--Dockerfile鏡像制作

目錄 一:Docker 鏡像管理 1:Docker 鏡像結構 2:Dockerfile介紹 二:Dockerfile 語法基礎 1:基礎指令 2:環境設置指令 3:文件操作指令 4:執行命令指令 5:網絡和暴露端口指令 6.容器掛載指令 三&#xff1a;dockerfile案例 1.構建nginx容器 一:Docker 鏡像管理 Docker…

數字時代的“靈魂”之爭:虛擬人形象的著作權困局與破局之道

首席數據官高鵬律師數字經濟團隊創作&#xff0c;AI輔助。 一、虛擬人的“數字生命”&#xff1a;一場關于“靈魂”的商業博弈 當一個虛擬偶像的“眼神”被復刻成千萬個相似的數字面孔&#xff0c;當一段虛擬主播的“聲音”被拆解為可交易的數據碎片——我們正在見證一個“數…

小型CI/CD搭建(TODO)

1 方案 因為是在國內&#xff0c;所以gitbub Actions&#xff0c;??Azure DevOps?這些就直接拜拜了。 目前主流的大概是三種&#xff1a; 1 阿里云效/騰訊云CODING 2 GitLab CE GitLab Runner 3 Gitee Jenkins deepeseek比較了一下如下&#xff1a; 阿里云效 vs Git…

Android Studio flutter項目運行、打包時間太長

Android Studio&#xff1a;Android Studio Meerkat Feature Drop | 2024.3.2 Patch 1 flutter Sdk&#xff1a;3.29.3 系統&#xff1a;windows flutter sdk從2.10.5升級到3.29.3&#xff0c;但是Flutter 3.16開始新增了使用 Gradle聲明式 plugins {} 塊&#xff0c;gradle文…

【OpenGL學習】(六)圖形添加紋理

文章目錄 【OpenGL學習】&#xff08;六&#xff09;圖形添加紋理紋理環繞紋理過濾紋理顏色與頂點顏色混合 OpenGL紋理介紹&#xff1a;https://learnopengl-cn.github.io/01%20Getting%20started/06%20Textures/ 【OpenGL學習】&#xff08;六&#xff09;圖形添加紋理 項目…

allure安裝

一、安裝java 需要安裝java環境&#xff0c;不安裝的話在運行前會報錯下列問題&#xff08;前提是安裝了allure未安裝java&#xff09; 1.官網地址&#xff1a;https://www.oracle.com/ 2.點擊”Download Java“ 3.選擇JDK正式版本&#xff08;需要jdk1.8&#xff09; 4.選擇W…

SpringBoot基于JavaWeb的城鄉居民基本醫療信息管理系統

概述 一個基于SpringBoot框架開發的JavaWeb醫療信息管理系統&#xff0c;采用了現代化的技術架構&#xff0c;功能全面&#xff0c;非常適合作為學習項目或二次開發的基礎。 主要內容 該系統主要包含以下核心功能模塊&#xff1a; ??用戶管理模塊?? 實現管理員、醫生、…

SQL變量聲明與賦值 分支 循環

– 變量 分支 循環 – declare 變量名 數據類型 – declare 關鍵字&#xff0c;作用聲明變量 – 變量名&#xff1a;以開頭 – 數據類型&#xff1a;數據庫中支持的數據類型&#xff1a;int varchar(n) text char(n) nvarchar(n) nchar(n) declare name varchar(255)– 定義多…

AWS S3 可觀測性最佳實踐

AWS S3 介紹 AWS S3&#xff08;Amazon Simple Storage Service&#xff09;是一種可擴展的對象存儲服務&#xff0c;提供高可用性、持久性和安全性。它允許用戶存儲和檢索任意數量的數據&#xff0c;并通過簡單的 Web 服務接口訪問這些數據。S3 支持多種存儲類別&#xff0c;…

Ubuntu下布署mediasoup-demo

一、引言 mediasoup是一個強大的SFU架構的WebRTC流媒體服務器&#xff0c;憑借其多功能性、高性能和可擴展性&#xff0c;mediasoup成為構建多方視頻會議和實時流媒體應用程序的完美選擇。它具有聯播、SVC、傳輸BWE和更多尖端功能。本文介紹了mediasoup-demo在Ubuntu下的布署。…

【JVS更新日志】物聯網、智能排產APS、企業計劃、規則引擎6.25更新說明!

項目介紹 JVS是企業級數字化服務構建的基礎腳手架&#xff0c;主要解決企業信息化項目交付難、實施效率低、開發成本高的問題&#xff0c;采用微服務配置化的方式&#xff0c;提供了低代碼數據分析物聯網的核心能力產品&#xff0c;并構建了協同辦公、企業常用的管理工具等&…

解決git pull,push 每次操作輸入賬號密碼問題

服務器每次git pull 的時候都需要輸入賬號密碼&#xff0c;一勞永逸解決它。 解決方案&#xff1a; 找到項目下 .git /config 文件&#xff0c;然后打開&#xff0c;編輯 [rootiZbp11b24d3d7nc8uvjx9mZ .git]# ls branches config description FETCH_HEAD HEAD hooks i…

Netty:深入解析AbstractByteBufAllocator架構設計

AbstractByteBufAllocator 類結構分析 類結構概覽 public abstract class AbstractByteBufAllocator implements ByteBufAllocator {// 靜態常量static final int DEFAULT_INITIAL_CAPACITY 256;static final int DEFAULT_MAX_CAPACITY Integer.MAX_VALUE;// ...其他常量//…

Java 日志管理與分析

為什么需要日志 ■ 發?了什么&#xff08;What&#xff09;。 ■ 何時發?的&#xff08;When&#xff09;。 ■ 發?于何處&#xff08;Where&#xff09;。 ■ 誰參與其中&#xff08;Who&#xff09;。 ■ 參與者來源&#xff08;第?個Where&#xff0c;注意與上?的Wher…

bmc TrueSight 監控mysql配置

bmc TrueSight 監控mysql配置 1.將pat加入mysql組 useradd pat;echo patpassword|passwd --stdin pat usermod -aG mysql pat2.設置環境變量 查看文件是否存在[rootu1acmsdp01 ~]# find / -name mysql.sock /var/lib/mysql/mysql.sock ^C [rootu1acmsdp01 ~]# cd /var/lib/my…

WinAppDriver 自動化測試:C#篇

??親愛的技術愛好者們,熱烈歡迎來到 Kant2048 的博客!我是 Thomas Kant,很開心能在CSDN上與你們相遇~?? 本博客的精華專欄: 【自動化測試】 【測試經驗】 【人工智能】 【Python】