gRPC Python 详细入门教程(一)

作者:kuan_li_lyg日期:2025/10/19

系列文章目录

目录

系列文章目录

前言

0.1 主要应用场景

0.2 核心优势特性

一、快速入门

1.1 先决条件

1.1.1 gRPC

1.1.2 gRPC 工具

1.2 下载示例代码

1.3 运行一个 gRPC 应用程序

1.4 更新gRPC服务

1.5 生成 gRPC 代码

1.6 更新并运行应用程序

1.6.1 更新服务器

1.6.2 更新客户端

1.6.3 运行!

二、基础教程

2.1 为何选择gRPC?

2.2 示例代码与环境配置

2.3 定义服务

2.4 生成客户端和服务器代码

2.4.1 生成具有自定义包路径的 gRPC 接口

2.5 创建服务器

2.5.1 实现 RouteGuide

2.5.1.1 简单 RPC

2.5.1.2 响应流式RPC

2.5.1.3 请求流式 RPC

2.5.1.4 双向流式RPC

2.5.1.5 启动服务器

2.6 创建客户端

2.6.1 创建存根

2.6.2 调用服务方法

2.6.2.1 简单RPC

2.6.2.2 响应流式RPC

2.6.2.3 请求流式RPC

2.6.2.4 双向流式RPC

2.7 试试看!

三、ALTS 身份验证

3.1 概述

3.2 采用 ALTS 传输安全协议的 gRPC 客户端

3.3 采用ALTS传输安全协议的gRPC服务器

四、生成的代码引用

4.1 示例

4.2 代码元素

4.2.1 存根类

4.2.2 Servicer类

4.2.3 注册函数


前言

gRPC 是一个现代开源的高性能远程过程调用(RPC)框架,可在任何环境中运行。它能高效连接数据中心内及跨数据中心的服务,并支持可插拔的负载均衡、追踪、健康检查和身份验证功能。它同样适用于分布式计算的最后一公里,将设备、移动应用和浏览器连接至后端服务。

0.1 主要应用场景

  • 高效连接微服务架构中的多语言服务
  • 连接移动设备、浏览器客户端与后端服务
  • 生成高效客户端库

0.2 核心优势特性

  • 支持11种语言的原生客户端库
  • 高效传输与简洁的服务定义框架
  • 基于HTTP/2传输的双向流式传输
  • 可插拔认证、追踪、负载均衡与健康检查

**一、**快速入门

本指南通过一个简单的可运行示例,帮助您在 Python 中开始使用 gRPC。

1.1 先决条件

  • Python 3.7 或更高版本
  • pip 版本 9.0.1 或更高版本

如有必要,请升级您的 pip 版本:

python -m pip install --upgrade pip

1.1.1 gRPC

安装 gRPC:

python -m pip install grpcio

或者,要系统范围安装:

sudo python -m pip install grpcio

1.1.2 gRPC 工具

Python 的 gRPC 工具包含协议缓冲编译器 protoc 以及用于从 .proto 服务定义生成服务器和客户端代码的专用插件。在本快速入门示例的前半部分,我们已从 helloworld.proto 生成服务器和客户端存根代码,但后续快速入门、后续教程以及您自己的项目仍需使用这些工具。

安装 gRPC 工具请执行:

python -m pip install grpcio-tools

1.2 下载示例代码

您需要本地副本的示例代码才能完成本快速入门指南。请从我们的 GitHub 仓库下载示例代码(以下命令会克隆整个仓库,但您只需示例代码即可完成本快速入门及其他教程):

1# Clone the repository to get the example code:
2git clone -b v1.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
3# Navigate to the "hello, world" Python example:
4cd grpc/examples/python/helloworld

1.3 运行一个 gRPC 应用程序

从 examples/python/helloworld 目录:

  1. 运行服务器:
    python greeter_server.py
  2. 在另一个终端中运行客户端:
    python greeter_client.py

恭喜!您刚刚成功运行了一个基于gRPC的客户端-服务器应用程序。

1.4 更新gRPC服务

现在让我们看看如何在服务器端添加一个额外方法供客户端调用,从而更新应用程序。我们的gRPC服务采用协议缓冲区定义;关于如何在.proto文件中定义服务,您可查阅《gRPC入门》和《基础教程》获取更多信息。当前您只需了解:服务器端和客户端“存根”均包含一个SayHello RPC方法,该方法接收客户端的HelloRequest参数并返回服务器的HelloReply响应,其定义如下:

1// The greeting service definition.
2service Greeter {
3  // Sends a greeting
4  rpc SayHello (HelloRequest) returns (HelloReply) {}
5}
6
7// The request message containing the user's name.
8message HelloRequest {
9  string name = 1;
10}
11
12// The response message containing the greetings
13message HelloReply {
14  string message = 1;
15}

让我们更新这个文件,使 Greeter 服务拥有两个方法。编辑 examples/protos/helloworld.proto 文件,并添加一个新的 SayHelloAgain 方法,其请求和响应类型与原有方法相同:

1// The greeting service definition.
2service Greeter {
3  // Sends a greeting
4  rpc SayHello (HelloRequest) returns (HelloReply) {}
5  // Sends another greeting
6  rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
7}
8
9// The request message containing the user's name.
10message HelloRequest {
11  string name = 1;
12}
13
14// The response message containing the greetings
15message HelloReply {
16  string message = 1;
17}

记得保存文件!

1.5 生成 gRPC 代码

接下来,我们需要更新应用程序使用的 gRPC 代码,使其采用新的服务定义。

在 examples/python/helloworld 目录下运行:

python -m grpc_tools.protoc -I../../protos --python_out=. --pyi_out=. --grpc_python_out=. ../../protos/helloworld.proto

这将重新生成包含生成的请求和响应类的 helloworld_pb2.py 文件,以及包含生成的客户端和服务器类的 helloworld_pb2_grpc.py 文件。

1.6 更新并运行应用程序

我们现在拥有新生成的服务器和客户端代码,但仍需在示例应用程序的人工编写部分实现并调用新方法。

1.6.1 更新服务器

在同一目录下打开greeter_server.py文件。按以下方式实现新方法:

1class Greeter(helloworld_pb2_grpc.GreeterServicer):
2
3    def SayHello(self, request, context):
4        return helloworld_pb2.HelloReply(message=f"Hello, {request.name}!")
5
6    def SayHelloAgain(self, request, context):
7        return helloworld_pb2.HelloReply(message=f"Hello again, {request.name}!")
8...

1.6.2 更新客户端

在同一目录下,打开greeter_client.py文件。调用新方法时如下所示:

1def run():
2    with grpc.insecure_channel('localhost:50051') as channel:
3        stub = helloworld_pb2_grpc.GreeterStub(channel)
4        response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
5        print("Greeter client received: " + response.message)
6        response = stub.SayHelloAgain(helloworld_pb2.HelloRequest(name='you'))
7        print("Greeter client received: " + response.message)

1.6.3 运行!

就像我们之前做的那样,从 examples/python/helloworld 目录:

  1. 运行服务器:
    python greeter_server.py
  2. 在另一个终端中运行客户端:
    python greeter_client.py

二、基础教程

Python中gRPC的基础教程介绍。

本教程为Python程序员提供gRPC入门指南。

通过实践本示例,您将学会:

  • 在.proto文件中定义服务
  • 使用协议缓冲编译器生成服务器和客户端代码
  • 运用Python gRPC API编写服务的简单客户端与服务器

本教程假设您已阅读《gRPC入门指南》并熟悉协议缓冲区。更多内容可参阅proto3语言指南和Python生成的代码指南。

2.1 为何选择gRPC?

我们的示例是一个简单的路线映射应用程序,允许客户端获取路线沿途设施信息、创建路线摘要,并与服务器及其他客户端交换路线信息(如交通更新)。

借助 gRPC,我们只需在 .proto 文件中定义服务一次,即可为 gRPC 支持的任意语言生成客户端和服务器。这些程序既可在大型数据中心的服务器环境运行,也能在个人平板设备上运行——不同语言和环境间的通信复杂性均由 gRPC 自动处理。同时还能享受协议缓冲区带来的所有优势,包括高效序列化、简洁的接口描述语言(IDL)以及便捷的接口更新机制。

2.2 示例代码与环境配置

本教程示例代码位于 grpc/grpc/examples/python/route_guide。下载示例请执行以下命令克隆 grpc 仓库:

git clone -b v1.74.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc

然后将当前目录切换到仓库中的 examples/python/route_guide 目录:

cd grpc/examples/python/route_guide

你还需要安装相关工具来生成服务器和客户端接口代码——如果尚未安装,请按照快速入门中的设置说明操作。

2.3 定义服务

(正如《gRPC入门》所述)第一步是使用协议缓冲区定义gRPC服务及方法请求/响应类型。完整.proto文件可参见examples/protos/route_guide.proto。

定义服务时,需在.proto文件中指定命名服务:

1service RouteGuide {
2   // (Method definitions not shown)
3}

然后在服务定义中定义 RPC 方法,指定其请求和响应类型。gRPC 允许定义四种服务方法,RouteGuide 服务中均使用了这些方法:

  • 一种简单的 RPC,客户端通过存根向服务器发送请求并等待响应返回,就像普通函数调用一样。
1// Obtains the feature at a given position.  
2rpc GetFeature(Point) returns (Feature) {}  
  • 响应流式RPC中,客户端向服务器发送请求后会获得一个流,用于读取返回的消息序列。客户端从返回的流中读取消息直至消息耗尽。如示例所示,通过在响应类型前添加stream关键字即可指定响应流式方法。
1// Obtains the Features available within the given Rectangle.  Results are  
2// streamed rather than returned at once (e.g. in a response message with a  
3// repeated field), as the rectangle may cover a large area and contain a  
4// huge number of features.  
5rpc ListFeatures(Rectangle) returns (stream Feature) {}  
  • 请求流式RPC中,客户端将消息序列写入并发送至服务器,同样使用提供的流。客户端完成消息写入后,将等待服务器读取全部消息并返回响应。通过在请求类型前添加stream关键字即可指定请求流式方法。
1// Accepts a stream of Points on a route being traversed, returning a  
2// RouteSummary when traversal is completed.  
3rpc RecordRoute(stream Point) returns (RouteSummary) {}  
  • 一种双向流式RPC,双方均通过读写流发送消息序列。两个流独立运行,因此客户端和服务器可按任意顺序读写:例如服务器可等待接收所有客户端消息后再写入响应,也可交替读写消息,或采用其他读写组合方式。每个流中的消息顺序均得到保留。要指定此类方法,需在请求和响应前均添加 stream 关键字。
1// Accepts a stream of RouteNotes sent while a route is being traversed,  
2// while receiving other RouteNotes (e.g. from other users).  
3rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}  

您的 .proto 文件还包含了服务方法中所有请求和响应类型的协议缓冲区消息类型定义——例如,以下是 Point 消息类型:

1// Points are represented as latitude-longitude pairs in the E7 representation
2// (degrees multiplied by 10**7 and rounded to the nearest integer).
3// Latitudes should be in the range +/- 90 degrees and longitude should be in
4// the range +/- 180 degrees (inclusive).
5message Point {
6  int32 latitude = 1;
7  int32 longitude = 2;
8}

2.4 生成客户端和服务器代码

接下来,您需要从 .proto 服务定义中生成 gRPC 客户端和服务器接口。

首先,安装 grpcio-tools 包:

pip install grpcio-tools

使用以下命令生成 Python 代码:

python -m grpc_tools.protoc -I../../protos --python_out=. --pyi_out=. --grpc_python_out=. ../../protos/route_guide.proto

请注意,由于我们在示例目录中已提供生成的代码版本,执行此命令将重新生成相应文件而非创建新文件。生成的代码文件名为 route_guide_pb2.py 和 route_guide_pb2_grpc.py,包含:

  • route_guide.proto 中定义的消息类
  • route_guide.proto 中定义的服务类
    • RouteGuideStub(客户端可用于调用 RouteGuide RPC)
    • RouteGuideServicer(定义 RouteGuide 服务的实现接口)
  • route_guide.proto 中定义的服务函数
    • add_RouteGuideServicer_to_server(将 RouteGuideServicer 添加至 grpc.Server)

注释

pb2 中的 2 表示生成的代码遵循 Protocol Buffers Python API 第 2 版。第 1 版已废弃。这与 Protocol Buffers 语言版本无关,后者由 .proto 文件中的 syntax = “proto3” 或 syntax = “proto2” 指定。

2.4.1 生成具有自定义包路径的 gRPC 接口

若要生成具有自定义包路径的 gRPC 客户端接口,可使用 grpc_tools.protoc 命令配合 -I 参数。此方法允许您为生成的文件指定自定义包名称。

以下是生成具有自定义包路径的 gRPC 客户端接口的示例命令:

1python -m grpc_tools.protoc -Igrpc/example/custom/path=../../protos \
2  --python_out=. --grpc_python_out=. \
3  ../../protos/route_guide.proto

生成的文件将放置在 ./grpc/example/custom/path/ 目录下:

  • ./grpc/example/custom/path/route_guide_pb2.py
  • ./grpc/example/custom/path/route_guide_pb2_grpc.py

通过此配置,生成的route_guide_pb2_grpc.py文件将正确导入自定义包结构中的protobuf定义,如下所示:

import grpc.example.custom.path.route_guide_pb2 as route_guide_pb2

通过这种方法,您可以确保文件在指定的包路径下正确调用彼此。该方法允许您为gRPC客户端接口维护自定义的包结构。

2.5 创建服务器

首先了解如何创建 RouteGuide 服务器。若您仅需创建 gRPC 客户端,可跳过本节直接进入创建客户端部分(不过您可能仍会发现它很有趣!)。

创建并运行 RouteGuide 服务器包含两项工作:

  • 实现由服务定义生成的服务接口,并添加执行服务实际“工作”的函数。
  • 运行 gRPC 服务器以监听客户端请求并传输响应。

示例 RouteGuide 服务器位于 examples/python/route_guide/route_guide_server.py。

2.5.1 实现 RouteGuide

route_guide_server.py 包含 RouteGuideServicer 类,该类继承自生成的 route_guide_pb2_grpc.RouteGuideServicer 类:

1# RouteGuideServicer provides an implementation of the methods of the RouteGuide service.
2class RouteGuideServicer(route_guide_pb2_grpc.RouteGuideServicer):

RouteGuideServicer 实现了所有 RouteGuide 服务方法。

2.5.1.1 简单 RPC

首先来看最简单的类型 GetFeature,它仅从客户端获取一个点,然后从数据库中返回对应的特征信息,并封装在 Feature 中。

1def GetFeature(self, request, context):
2    feature = get_feature(self.db, request)
3    if feature is None:
4        return route_guide_pb2.Feature(name="", location=request)
5    else:
6        return feature

该方法接收一个用于RPC的route_guide_pb2.Point请求,以及一个提供RPC特定信息(如超时限制)的grpc.ServicerContext对象。它返回一个route_guide_pb2.Feature响应。

2.5.1.2 响应流式RPC

现在来看下一个方法。ListFeatures是一个响应流式RPC,用于向客户端发送多个特征。

1def ListFeatures(self, request, context):
2    left = min(request.lo.longitude, request.hi.longitude)
3    right = max(request.lo.longitude, request.hi.longitude)
4    top = max(request.lo.latitude, request.hi.latitude)
5    bottom = min(request.lo.latitude, request.hi.latitude)
6    for feature in self.db:
7        if (
8            feature.location.longitude >= left
9            and feature.location.longitude <= right
10            and feature.location.latitude >= bottom
11            and feature.location.latitude <= top
12        ):
13            yield feature

此处请求消息为 route_guide_pb2.Rectangle 对象,客户端希望在其内部查找特征。该方法不会返回单一响应,而是返回零个或多个响应。

2.5.1.3 请求流式 RPC

请求流式方法 RecordRoute 使用请求值迭代器,并返回单个响应值。

1def RecordRoute(self, request_iterator, context):
2    point_count = 0
3    feature_count = 0
4    distance = 0.0
5    prev_point = None
6
7    start_time = time.time()
8    for point in request_iterator:
9        point_count += 1
10        if get_feature(self.db, point):
11            feature_count += 1
12        if prev_point:
13            distance += get_distance(prev_point, point)
14        prev_point = point
15
16    elapsed_time = time.time() - start_time
17    return route_guide_pb2.RouteSummary(
18        point_count=point_count,
19        feature_count=feature_count,
20        distance=int(distance),
21        elapsed_time=int(elapsed_time),
22    )
2.5.1.4 双向流式RPC

最后,我们来看双向流式方法RouteChat。

1def RouteChat(self, request_iterator, context):
2    prev_notes = []
3    for new_note in request_iterator:
4        for prev_note in prev_notes:
5            if prev_note.location == new_note.location:
6                yield prev_note
7        prev_notes.append(new_note)

该方法的语义结合了请求流式处理方法和响应流式处理方法的特性。它接收请求值的迭代器,自身则作为响应值的迭代器。

2.5.1.5 启动服务器

在实现所有 RouteGuide 方法后,下一步是启动 gRPC 服务器,以便客户端能够实际使用您的服务:

1def serve():
2    server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
3    route_guide_pb2_grpc.add_RouteGuideServicer_to_server(RouteGuideServicer(), server)
4    server.add_insecure_port("[::]:50051")
5    server.start()
6    server.wait_for_termination()

服务器 start() 方法是非阻塞的。将创建一个新线程来处理请求。调用 server.start() 的线程在此期间通常没有其他工作可做。这种情况下,可调用 server.wait_for_termination() 使调用线程在服务器终止前保持干净阻塞状态。

2.6 创建客户端

完整的示例客户端代码详见examples/python/route_guide/route_guide_client.py。

2.6.1 创建存根

调用服务方法前需先创建存根。

我们实例化route_guide_pb2_grpc模块中的RouteGuideStub类,该类由.proto文件生成。

1channel = grpc.insecure_channel('localhost:50051')
2stub = route_guide_pb2_grpc.RouteGuideStub(channel)

2.6.2 调用服务方法

对于返回单一响应的RPC方法(即“响应单态”方法),gRPC Python同时支持同步(阻塞)和异步(非阻塞)控制流语义。对于响应流式RPC方法,调用会立即返回响应值的迭代器。调用该迭代器的next()方法将阻塞,直至迭代器可返回响应。

2.6.2.1 简单RPC

对简单RPC方法GetFeature的同步调用几乎与调用本地方法同样简单。RPC调用会等待服务器响应,最终返回响应或抛出异常:

feature = stub.GetFeature(point)

对 GetFeature 的异步调用类似,但如同在线程池中异步调用本地方法:

1feature_future = stub.GetFeature.future(point)
2feature = feature_future.result()
2.6.2.2 响应流式RPC

调用响应流式ListFeatures与处理序列类型类似:

for feature in stub.ListFeatures(rectangle):

2.6.2.3 请求流式RPC

调用请求流式RecordRoute类似于向本地方法传递迭代器。如同上述仅返回单个响应的简单RPC,它既可同步调用也可异步调用:

route_summary = stub.RecordRoute(point_iterator)

1route_summary_future = stub.RecordRoute.future(point_iterator)
2route_summary = route_summary_future.result()
2.6.2.4 双向流式RPC

调用双向流式RouteChat时(与服务端情况相同),请求流式与响应流式的语义会同时生效:

for received_route_note in stub.RouteChat(sent_route_note_iterator):

2.7 试试看!

运行服务器:

python route_guide_server.py

从另一个终端运行客户端:

python route_guide_client.py

三、ALTS 身份验证

使用应用层传输安全(ALTS)在 Python 中实现 gRPC 身份验证的概述。

3.1 概述

应用层传输安全(ALTS)是由谷歌开发的双向认证与传输加密系统,用于保障谷歌基础设施内的RPC通信安全。ALTS与双向TLS类似,但经过专门设计和优化以满足谷歌生产环境的需求。更多详情请参阅ALTS白皮书。

gRPC中的ALTS具备以下特性:

  • 创建以ALTS作为传输安全协议的gRPC服务器与客户端。
  • ALTS连接提供端到端隐私保护与完整性保障。
  • 应用程序可访问对等方信息(如对等服务账户)。
  • 支持客户端授权与服务器授权机制。
  • 启用ALTS仅需极少代码修改。

gRPC用户只需少量代码即可配置应用程序使用ALTS作为传输安全协议。

请注意,若应用程序在 Compute Engine 或 Google Kubernetes Engine (GKE) 上运行,ALTS 将实现全部功能。

3.2 采用 ALTS 传输安全协议的 gRPC 客户端

gRPC 客户端可使用 ALTS 凭证连接服务器,如下代码片段所示:

1import grpc
2
3channel_creds = grpc.alts_channel_credentials()
4channel = grpc.secure_channel(address, channel_creds)

3.3 采用ALTS传输安全协议的gRPC服务器

gRPC服务器可使用ALTS凭据允许客户端连接,如下所示:

1import grpc
2
3server = grpc.server(futures.ThreadPoolExecutor())
4server_creds = grpc.alts_server_credentials()
5server.add_secure_port(server_address, server_creds)

四、生成的代码引用

gRPC Python依赖协议缓冲区编译器(protoc)生成代码。它通过插件将普通protoc生成的代码补充为包含gRPC特异性代码的代码。对于包含 gRPC 服务的 .proto 服务描述文件,普通 protoc 生成的代码会被合成到 _pb2.py 文件中,而 gRPC 专属代码则存放在 _pb2_grpc.py 文件里。后者作为 Python 模块会导入前者。本页重点介绍生成的代码中 gRPC 专属的子集。

4.1 示例

考虑以下 FortuneTeller proto 服务:

1service FortuneTeller {
2  // Returns the horoscope and zodiac sign for the given month and day.
3  rpc TellFortune(HoroscopeRequest) returns (HoroscopeResponse) {
4    // errors: invalid month or day, fortune unavailable
5  }
6
7  // Replaces the fortune for the given zodiac sign with the provided one.
8  rpc SuggestFortune(SuggestionRequest) returns (SuggestionResponse) {
9    // errors: invalid zodiac sign
10  }
11}

当服务被编译时,gRPC协议插件会生成类似以下的_pb2_grpc.py文件:

1import grpc
2
3import fortune_pb2
4
5class FortuneTellerStub(object):
6
7  def __init__(self, channel):
8    """Constructor.
9
10    Args:
11      channel: A grpc.Channel.
12    """
13    self.TellFortune = channel.unary_unary(
14        '/example.FortuneTeller/TellFortune',
15        request_serializer=fortune_pb2.HoroscopeRequest.SerializeToString,
16        response_deserializer=fortune_pb2.HoroscopeResponse.FromString,
17        )
18    self.SuggestFortune = channel.unary_unary(
19        '/example.FortuneTeller/SuggestFortune',
20        request_serializer=fortune_pb2.SuggestionRequest.SerializeToString,
21        response_deserializer=fortune_pb2.SuggestionResponse.FromString,
22        )
23
24
25class FortuneTellerServicer(object):
26
27  def TellFortune(self, request, context):
28    """Returns the horoscope and zodiac sign for the given month and day.
29    errors: invalid month or day, fortune unavailable
30    """
31    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
32    context.set_details('Method not implemented!')
33    raise NotImplementedError('Method not implemented!')
34
35  def SuggestFortune(self, request, context):
36    """Replaces the fortune for the given zodiac sign with the provided
37one.
38    errors: invalid zodiac sign
39    """
40    context.set_code(grpc.StatusCode.UNIMPLEMENTED)
41    context.set_details('Method not implemented!')
42    raise NotImplementedError('Method not implemented!')
43
44
45def add_FortuneTellerServicer_to_server(servicer, server):
46  rpc_method_handlers = {
47      'TellFortune': grpc.unary_unary_rpc_method_handler(
48          servicer.TellFortune,
49          request_deserializer=fortune_pb2.HoroscopeRequest.FromString,
50          response_serializer=fortune_pb2.HoroscopeResponse.SerializeToString,
51      ),
52      'SuggestFortune': grpc.unary_unary_rpc_method_handler(
53          servicer.SuggestFortune,
54          request_deserializer=fortune_pb2.SuggestionRequest.FromString,
55          response_serializer=fortune_pb2.SuggestionResponse.SerializeToString,
56      ),
57  }
58  generic_handler = grpc.method_handlers_generic_handler(
59      'example.FortuneTeller', rpc_method_handlers)
60  server.add_generic_rpc_handlers((generic_handler,))

4.2 代码元素

生成的gRPC代码首先导入grpc包和由protoc合成的普通_pb2模块,该模块定义了非gRPC特有的代码元素,例如对应协议缓冲区消息的类以及反射使用的描述符。

对于.proto文件中的每个服务Foo,会生成三个主要元素:

  • 存根类:FooStub,用于客户端连接gRPC服务。
  • 服务实现类:FooServicer,用于服务器端实现gRPC服务。
  • 注册函数:add_FooServicer_to_server,用于将服务实现类注册到grpc.Server对象。

4.2.1 存根类

生成的Stub类供gRPC客户端使用。其构造函数接收 grpc.Channel 对象并初始化存根。对于服务中的每个方法,初始化器都会在存根对象中添加同名属性。根据 RPC 类型(单一调用或流式调用),该属性的值将分别是 UnaryUnaryMultiCallable、UnaryStreamMultiCallable、StreamUnaryMultiCallable 或 StreamStreamMultiCallable 类型的可调用对象。

4.2.2 Servicer类

针对每个服务,系统会生成Servicer类作为服务实现的基类。服务中的每个方法都会在Servicer类中生成对应函数,需用服务实现代码覆盖该函数。原生.proto文件中代码元素的注释将作为文档字符串出现在生成的Python代码中。

4.2.3 注册函数

为每个服务生成一个函数,用于将实现该服务的Servicer对象注册到grpc.Server对象上,以便服务器将查询路由至对应服务器。该函数接受两个参数:实现Servicer的对象(通常是上述生成的Servicer代码元素子类的实例)以及grpc.Server对象。


gRPC Python 详细入门教程(一)》 是转载文章,点击查看原文


相关推荐


AI无人机助力生态智慧农田倒伏检测与防控,基于最新以注意力为核心的YOLOv12全系列【n/s/m/l/x】参数模型开发构建无人机航拍智慧生态农田场景下稻田作物倒伏智能化检测预警系统
Together_CZ2025/10/17

在广袤的稻田中,农作物的生长状态直接关系到粮食的产量和质量。然而,自然环境的不确定性,如大风等恶劣天气,常常给农作物带来倒伏的风险。倒伏不仅会导致产量下降,还会给后续的机械化收割带来极大的困难,甚至造成严重的浪费。传统的农田作业模式在面对这些问题时显得力不从心,而随着 AI 智能化技术的快速发展,传统农业正迎来一场深刻的变革。 一、传统农田作业的困境 在传统的稻田种植中,农民们依靠丰富的经验和敏锐的观察力来管理农田。然而,面对大面积的农田,人工巡查的方式效率低下,且难以及时发现所有倒伏区域。


【Java Xml】Apache Commons Digester3解析
Lucky_Turtle2025/10/16

文章目录 概述前期准备使用1、简单读取示例2、多个标签读取示例 细节问题addSetNext顺序 参考 概述 官网 写入查看另一篇:https://blog.csdn.net/qq_45742250/article/details/153191615 前期准备 maven <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-digester3 --> <dependency> <gr


elasticsearch-8.12.2集群部署
peng1792025/10/15

一:下载和解压JDK安装包 下载地址:https://mirrors.huaweicloud.com/openjdk/17/openjdk-17_linux-x64_bin.tar.gz 解压:tar -zxvf jdk-17_linux-x64_bin.tar.gz 二:配置JDK环境 编辑/etc/profile文件: vi /etc/profile    JAVA_HOME=/opt/jdk/jdk-17    PATH=$JAVA_HOME/bin:$PATH 保存后执行s


机器人控制基础:步进驱动器的选型总结
start_up_go2025/10/13

目录 一、选型核心维度:先匹配电机,再适配需求 1. 基础匹配:与步进电机参数严格兼容 2. 应用需求导向:确定驱动器性能与功能 3. 功能需求:按需选择保护与辅助功能 4. 环境适应性:匹配使用场景的物理条件 二、选型关键步骤:从参数到落地的 5 步流程 步骤 1:明确步进电机的核心参数 步骤 2:定义应用的核心需求 步骤 3:筛选驱动器的基础参数 步骤 4:验证功能与兼容性 步骤 5:预留余量,避免极限运行 三、选型注意事项:避开常见误区 四、典型场景选型示例


【k8s】基础概念+下载安装教程
_BugMan2025/10/12

目录 k8s提供的核心能力 1. 自动化运维与自愈能力 2. 服务的弹性伸缩 3. 服务发现与负载均衡 4. 发布与回滚 5. 配置与秘钥管理 组件 核心组件 概念组件 扩展组件 下载安装 测试 kubectl命令 k8s提供的核心能力 k8s可以理解为一个 1. 自动化运维与自愈能力 这是 K8S 最吸引人的能力之一。 自动重启:如果容器崩溃,K8S 会自动重启它。 自动替换:如果整个节点(服务器)宕机,K8S 会检测到它上面的容器失效,并在其他


对《DDD本质论》一文的解读
canonical_entropy2025/10/10

在《DDD本质论:从哲学到数学,再到工程实践的完整指南之理论篇》中,我们建立了一套从第一性原理出发的DDD理论体系。由于原文理论密度较高、概念间关系精微,为帮助读者更清晰地把握其思想脉络,我们设计了一项思想实验,并借助AI进行体系梳理与对比。 我们首先向AI提出以下问题: DDD领域驱动设计的概念有哪些?这些概念之间的相互关系是什么。如果要逐一去掉这些概念,你会按照什么顺序,为什么? 换言之,如果从第一性原理出发,如何逐步推导出这些概念的相互关系? 不要把任何技术看作是一个不可切分的整体,任何


tcp服务器
liuy96152025/10/9

🧩 一、总体架构思路 TCP 服务器的基本流程: 创建监听套接字 → 绑定 IP 和端口 → 监听端口 → 接受连接 → 通信收发 → 关闭连接 伪代码框架: int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); // 创建TCP套接字 bind(listen_fd, …); // 绑定地址和端口 listen(listen_fd, SOMAXCONN);


Vue3 EffectScope 源码解析与理解
excel2025/10/7

1. 全局变量与基础类定义 activeEffectScope:表示当前正在运行的 effect 作用域。 EffectScope 类:用来管理一组副作用(ReactiveEffect),提供生命周期控制。 import type { ReactiveEffect } from './effect' import { warn } from './warning' // 当前全局正在运行的作用域 export let activeEffectScope: EffectScope | und


Linus 眼中,编程 AI 的真实价值如何?
飞哥数智谈2025/10/6

今天刷到了一段视频,是 Linux 之父 Linus Torvalds 与 VMware 副总裁兼首席开源官 Dirk Hohndel 的一段对话。 内容挺有意思,分享给大家。 主要有两个话题: AI 只是打了鸡血的自动纠错 AI 幻觉带来了 bug 话题是由 Dirk Hohndel 提出,由 Linus Torvalds 进行回答的。 AI 是打了鸡血的自动纠错 针对这一点,Linus Torvalds 认为这一说法有一定的合理性,但 AI 在编程领域的真正潜力是可以成为一个识别“明显愚


从传输层协议到 UDP:轻量高效的传输选择
渡我白衣2025/10/5

前言 在计算机网络中,传输层是一个关键的层级,它为应用进程之间的通信提供了端到端的传输服务。常见的传输层协议有 TCP 和 UDP。前者强调可靠、面向连接的传输,而后者则提供轻量级、无连接的通信方式。传输层位于网络层之上、应用层之下,为进程之间提供端到端的数据传输服务。要理解 UDP 协议,我们需要先了解 传输层的功能与常见协议,再深入探讨为什么 UDP 在今天的网络环境中仍占据着举足轻重的地位。 一、传输层的基本概念 在 OSI 七层模型 和 TCP/IP 五层模型 中,传输层是第四层,它的主

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0