gRPC是Google开源的高性能远程过程调用框架,基于HTTP/2协议传输,默认使用Protobuf作为接口定义语言和消息序列化工具,C++版本的gRPC能够充分发挥框架性能优势,适合对性能要求较高的分布式系统开发场景。

环境准备
首先需要安装gRPC C++依赖,包括Protobuf编译器和gRPC核心库。如果是Ubuntu系统,可以通过包管理器快速安装:
# 安装依赖工具 sudo apt update sudo apt install -y build-essential autoconf libtool pkg-config # 安装protobuf sudo apt install -y protobuf-compiler libprotobuf-dev # 安装gRPC sudo apt install -y libgrpc++-dev grpc-compiler
定义proto接口文件
使用Protobuf定义服务接口和消息格式,创建hello.proto文件:
syntax = "proto3";
package hello;
// 定义请求消息
message HelloRequest {
string name = 1;
}
// 定义响应消息
message HelloReply {
string message = 1;
}
// 定义服务
service Greeter {
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
执行以下命令生成C++代码:
protoc --cpp_out=. --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` hello.proto
执行后会生成hello.pb.h、hello.pb.cc、hello.grpc.pb.h、hello.grpc.pb.cc四个文件。
编写服务端代码
服务端需要实现proto定义的服务接口,创建server.cpp:
#include <iostream>
#include <string>
#include <grpc/grpc.h>
#include <grpcpp/grpcpp.h>
#include "hello.pb.h"
#include "hello.grpc.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
using hello::HelloRequest;
using hello::HelloReply;
using hello::Greeter;
// 实现Greeter服务
class GreeterServiceImpl final : public Greeter::Service {
Status SayHello(ServerContext* context, const HelloRequest* request,
HelloReply* reply) override {
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer() {
std::string server_address("0.0.0.0:50051");
GreeterServiceImpl service;
ServerBuilder builder;
// 监听端口
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// 注册服务
builder.RegisterService(&service);
// 构建并启动服务器
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// 阻塞等待请求
server->Wait();
}
int main(int argc, char** argv) {
RunServer();
return 0;
}
编写客户端代码
客户端需要调用服务端提供的接口,创建client.cpp:
#include <iostream>
#include <string>
#include <grpc/grpc.h>
#include <grpcpp/grpcpp.h>
#include "hello.pb.h"
#include "hello.grpc.pb.h"
using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;
using hello::HelloRequest;
using hello::HelloReply;
using hello::Greeter;
class GreeterClient {
public:
GreeterClient(std::shared_ptr<Channel> channel)
: stub_(Greeter::NewStub(channel)) {}
std::string SayHello(const std::string& name) {
HelloRequest request;
request.set_name(name);
HelloReply reply;
ClientContext context;
// 调用远程方法
Status status = stub_->SayHello(&context, request, &reply);
if (status.ok()) {
return reply.message();
} else {
return "RPC failed";
}
}
private:
std::unique_ptr<Greeter::Stub> stub_;
};
int main(int argc, char** argv) {
// 连接服务端
GreeterClient greeter(grpc::CreateChannel(
"localhost:50051", grpc::InsecureChannelCredentials()));
std::string name("World");
std::string reply = greeter.SayHello(name);
std::cout << "Greeter received: " << reply << std::endl;
return 0;
}
编译运行
使用g++编译两个程序,需要链接gRPC和Protobuf库:
# 编译服务端 g++ -std=c++11 server.cpp hello.pb.cc hello.grpc.pb.cc -o server `pkg-config --libs grpc++ grpc protobuf` # 编译客户端 g++ -std=c++11 client.cpp hello.pb.cc hello.grpc.pb.cc -o client `pkg-config --libs grpc++ grpc protobuf`
先启动服务端:
./server
再启动客户端,会输出Greeter received: Hello World,说明远程调用成功。
注意事项
- 生产环境需要添加SSL/TLS认证,替换
InsecureServerCredentials和InsecureChannelCredentials为安全凭证 - proto文件的包名需要合理规划,避免不同服务之间的命名冲突
- 可以通过添加拦截器实现日志记录、超时控制等通用功能