有一种情况,我需要在我的服务器上实现 2 个版本的 grpc API。我该怎么做?
syntax = "proto3";
package greet.v1;
将帮助我向 pb2 自动生成的文件添加版本控制,但我完全不明白如何在同一服务器上组合 pb2(v1 和 v2)。也许有人有 Python 中 grpc 版本控制的例子?或者在一台服务器中使用 2 个版本可能是一种不好的做法,我应该使用另一个 pod 来获取新的 grpc 版本..
对于这个弱例子表示歉意。
我假设您在 v1 和 v2 之间进行了重大更改,并且具有以下类似内容:
protos/greet/v1/greet.proto
:
syntax = "proto3";
// Reflect package in folder path i.e. protos/greet/v1
package greet.v1;
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
message HelloRequest {
string name = 1;
}
message HelloReply {
string message = 1;
}
protos/greet/v2/greet.proto
:
syntax = "proto3";
// Reflect package in folder path i.e. protos/greet/v1
package greet.v2;
// Reuse (!) 'greet.v1.HelloReply'
import "greet/v1/greet.proto";
service Greeter {
rpc SayHello (HelloRequest) returns (greet.v1.HelloReply) {}
}
message HelloRequest {
fixed32 id = 1;
}
并且:
requirements.txt
:
grpcio==1.62.0
grpcio-reflection==1.62.0
grpcio-tools==1.62.0
protobuf==4.25.3
python3 -m venv venv
source venv/bin/activate
python3 -m pip install --requirement requirements.txt
python3 \
-m grpc_tools.protoc \
--proto_path=${PWD}/protos \
--python_out=${PWD} \
--pyi_out=${PWD} \
--grpc_python_out=${PWD} \
${PWD}/protos/greet/v1/greet.proto \
${PWD}/protos/greet/v2/greet.proto
并且:
main.py
:
# Python gRPC service reflection
from grpc_reflection.v1alpha import reflection
from concurrent import futures
import grpc
# v1
import greet.v1.greet_pb2 as greet_v1_pb2
import greet.v1.greet_pb2_grpc as greet_v1_pb2_grpc
class GreeterV1(greet_v1_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return greet_v1_pb2.HelloReply(message=f"Hello {request.name}")
# v2
import greet.v2.greet_pb2 as greet_v2_pb2
import greet.v2.greet_pb2_grpc as greet_v2_pb2_grpc
class GreeterV2(greet_v2_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return greet_v1_pb2.HelloReply(message=f"Hello {request.id}")
def serve():
# One service
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
# Adds v1 and v2 services
greet_v1_pb2_grpc.add_GreeterServicer_to_server(GreeterV1(), server)
greet_v2_pb2_grpc.add_GreeterServicer_to_server(GreeterV2(), server)
SERVICE_NAMES = (
greet_v1_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
greet_v2_pb2.DESCRIPTOR.services_by_name['Greeter'].full_name,
)
# Adds third service (!)
reflection.enable_server_reflection(SERVICE_NAMES, server)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
if __name__ == "__main__":
serve()
并且:
# Enumerate v1 Method
grpcurl -plaintext localhost:50051 list greet.v1.Greeter
greet.v1.Greeter.SayHello
# Invoke v1 Method
grpcurl -plaintext -d '{"name":"Freddie"}' localhost:50051 greet.v1.Greeter.SayHello
{
"message": "Hello Freddie"
}
# Enumerate v2 Method
grpcurl -plaintext localhost:50051 list greet.v2.Greeter
greet.v2.Greeter.SayHello
# Invoke v2 Method
grpcurl -plaintext -d '{"id":314159265}' localhost:50051 greet.v2.Greeter.SayHello
{
"message": "Hello 314159265"
}
注意 Python 的 gRPC 反射服务似乎不适用于
。describe {method}