如何在gRPC Protocol Buffer中实现版本控制 兼容多版本SayHello接口
实现方案
1. 拆分多版本Proto定义
首先将两个版本的接口拆分到独立的Proto文件中,分别声明不同的package,同时指定对应语言的生成配置:
目录结构参考
proto └── hello ├── v1 │ └── greet.proto # 原有v1版本定义 └── v2 └── greet.proto # 迭代后的v2版本定义
v1版本proto(proto/hello/v1/greet.proto)
保留原有定义,补充语言生成选项:
syntax = "proto3"; package hello.v1; // Go语言生成配置,指定生成路径和包名 option go_package = "你的项目模块路径/hello/v1;hellov1"; // C++生成配置可选,默认会按package生成hello::v1命名空间 option cc_namespace = "hello::v1"; service GreetService { rpc SayHello(SayHelloRequest) returns (SayHelloResponse) {} } message SayHelloRequest { string name = 1; } message SayHelloResponse { }
v2版本proto(proto/hello/v2/greet.proto)
使用新的package声明,写迭代后的接口定义:
syntax = "proto3"; package hello.v2; option go_package = "你的项目模块路径/hello/v2;hellov2"; option cc_namespace = "hello::v2"; service GreetService { rpc SayHello(SayHelloRequest) returns (SayHelloResponse) {} } message SayHelloRequest { string name = 1; uint32 age = 2; } message SayHelloResponse { string reply_message = 1; }
2. 服务端同时注册两个版本的服务
gRPC服务的唯一标识是包名.服务名,两个版本的包名不同,因此可以注册到同一个gRPC服务实例上,监听同一个端口:
- Go服务端:分别实现
hellov1.GreetServiceServer和hellov2.GreetServiceServer两个接口,调用hellov1.RegisterGreetServiceServer和hellov2.RegisterGreetServiceServer都注册到同一个grpc.Server实例即可。 - C++服务端:分别实现
hello::v1::GreetService::Service和hello::v2::GreetService::Service子类,调用grpc::ServerBuilder的RegisterService方法把两个服务实例都注册进去。
如果不想维护两套业务逻辑,可以在v1的接口实现中直接适配调用v2的业务逻辑,只需要做参数和返回值的转换即可。
3. 客户端按需调用对应版本
- C++客户端:生成的代码会自动归到
hello::v1和hello::v2两个命名空间下,按需选择命名空间下的Stub创建客户端调用即可。 - Go客户端:分别导入v1和v2的生成包,用对应包的
NewGreetServiceClient方法创建客户端调用即可。
内容的提问来源于stack exchange,提问作者Yongqi Z
相关产品推荐
相关产品推荐

