C++实现gRPC微服务核心为三步:编写.proto定义接口、用protoc生成C++代码(含.pb和.grpc.pb文件)、在服务端继承Service类实现RPC方法并在客户端通过Channel/Stub调用;需注意环境配置、生命周期管理及生产安全配置。

用 C++ 做 gRPC 微服务,核心是三步:写 .proto 定义接口、用 protoc 生成 C++ 代码、在服务端/客户端中调用生成的类和方法。不复杂,但容易卡在环境配置和生命周期管理上。
1. 环境准备与依赖安装
确保系统已安装:
- Protobuf 编译器(protoc ≥ 3.20),建议从 GitHub 官方发布页 下载预编译二进制,避免源码编译踩坑
- gRPC C++ 库(含 libgrpc, libgrpc++),推荐用 cmake + fetchcontent 在项目内拉取,避免系统级安装版本冲突
- CMake ≥ 3.16,支持
find_package(gRPC CONFIG)
不建议用 apt/yum 直接装 grpc-dev —— Ubuntu 的包常滞后且缺 C++ 插件支持。
2. 编写 .proto 文件并生成代码
例如定义一个简单用户服务:
立即学习“C++免费学习笔记(深入)”;
// user_service.proto
syntax = "proto3";
package example;
<p>service UserService {
rpc GetUser (UserRequest) returns (UserResponse);
}</p><p>message UserRequest {
int32 id = 1;
}</p><p>message UserResponse {
int32 id = 1;
string name = 2;
bool exists = 3;
}执行生成命令(需确保 protoc 能找到 gRPC 插件):
protoc -I . --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` user_service.proto protoc -I . --cpp_out=. user_service.proto
会生成 user_service.pb.h/.cc 和 user_service.grpc.pb.h/.cc。注意:两个 .h 文件都要 include,否则编译报错。
3. 实现服务端(同步方式)
继承自生成的 UserService::Service 类,重写 RPC 方法:
class UserServiceImpl final : public example::UserService::Service {
public:
Status GetUser(ServerContext* context, const UserRequest* request,
UserResponse* response) override {
if (request->id() == 123) {
response->set_id(123);
response->set_name("Alice");
response->set_exists(true);
} else {
response->set_exists(false);
}
return Status::OK;
}
};启动服务器时注意:
- 用
ServerBuilder添加监听地址(如"0.0.0.0:50051") - 注册服务实例(
builder.RegisterService(&service)) - 调用
builder.BuildAndStart()后,服务即运行 —— 不需要手动 run() 循环 - 记得保存返回的
std::unique_ptr<Server>,它控制生命周期;析构即关闭服务
4. 编写客户端调用
创建 Channel 和 Stub,再发起调用:
auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
auto stub = example::UserService::NewStub(channel);
<p>ClientContext context;
UserRequest req;
req.set_id(123);
UserResponse resp;</p><p>Status status = stub->GetUser(&context, req, &resp);
if (status.ok()) {
std::cout << "Name: " << resp.name() << "\n";
} else {
std::cerr << "RPC failed: " << status.error_message() << "\n";
}关键点:
- Channel 是线程安全的,可复用;Stub 不是,但通常每个线程一个或共享也没问题
-
InsecureChannelCredentials()仅用于开发;生产务必用ssl_credentials并配置根证书 - 同步调用会阻塞当前线程;如需异步,用
AsyncUnaryCall+CompletionQueue,但复杂度明显上升
整个流程跑通后,就可以加日志、健康检查(gRPC 自带 /healthz)、服务发现(配合 Consul/Etcd)、熔断(用 client-side interceptor 封装)了。C++ gRPC 性能高、控制强,适合对延迟和资源敏感的微服务场景。











