C++ 程序员一定要会的 RPC 框架:gRPC 从原理到实战,一次写通服务端和客户端

在分布式系统里,服务之间到底是怎么"像函数调用一样通信"的?

本文从 gRPC 的设计思想讲起,系统梳理它的能力、优缺点和真实使用场景,并用 C++ 实现一个完整可跑的 gRPC 服务端和客户端,一步到位,帮你真正理解 gRPC 在工程中的价值。

Github: github.com/grpc/grpc 官方文档:grpc.io/docs/langua...

为什么越来越多的系统在用 gRPC?

在早期的服务通信中,我们最常见的方案无非两种:

一种是 HTTP + JSON ,简单直观,但性能和规范性始终是瓶颈;

另一种是自己造 RPC 轮子,成本高、维护难、协议混乱。

gRPC 的出现,本质上就是在解决一个问题:
如何让跨进程、跨机器的服务调用,像本地函数调用一样自然?

gRPC 是 Google 开源的一套高性能 RPC 框架,核心特点有三个:

  • 基于 HTTP/2
  • 使用 Protocol Buffers 作为接口描述和序列化协议
  • 强约束的接口定义

这三个设计,决定了 gRPC 天生就不是"写给小脚本用的",而是面向中大型系统、微服务架构的通信基础设施。

优点和缺点

优点:

  • 性能好,延迟低
  • 接口规范清晰,适合团队协作
  • 工具链成熟,自动生成代码
  • 对微服务非常友好

缺点:

  • 学习成本高于 REST
  • 调试不如 HTTP 直观
  • 对浏览器不友好(需要 gRPC-Web)
  • protobuf 一旦设计不好,后期改动成本高

一句话总结:
gRPC 非常适合"服务与服务之间",但并不适合"直接暴露给人类使用"。

C++ gRPC 实战:从 0 到跑起来

下面用一个最简单的 HelloService,演示完整流程。

安装 gRPC 环境

bash 复制代码
sudo apt-get update
sudo apt-get install -y build-essential autoconf libtool pkg-config
# 安装 protobuf 编译器
sudo apt-get install -y libprotobuf-dev protobuf-compiler
# 安装 gRPC 库和插件
sudo apt-get install -y libgrpc++-dev libgrpc-dev

定义 proto 文件(hello.proto)

proto 复制代码
syntax = "proto3";

package hello;

service HelloService {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

生成 C++ 代码:

bash 复制代码
protoc --grpc_out=. --plugin=protoc-gen-grpc=`which grpc_cpp_plugin` hello.proto
protoc --cpp_out=. hello.proto

C++ 服务端实现

cpp 复制代码
#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>
#include "hello.grpc.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;

class HelloServiceImpl final : public hello::HelloService::Service {
public:
    Status SayHello(ServerContext* context,
                    const hello::HelloRequest* request,
                    hello::HelloReply* reply) override {
        reply->set_message("Hello, " + request->name());
        return Status::OK;
    }
};

int main() {
    std::string server_address("0.0.0.0:50051");
    HelloServiceImpl 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();
    return 0;
}

编译并启动服务

bash 复制代码
# 单文件编译
g++ -std=c++11 main.cpp hello.pb.cc hello.grpc.pb.cc \
-o hello_server \
`pkg-config --cflags --libs grpc++ grpc protobuf` \
-lgrpc++_reflection \
-lpthread

# 运行
./hello_server

C++ 客户端调用测试

c 复制代码
#include <iostream>
#include <memory>
#include <string>

#include <grpcpp/grpcpp.h>
#include "hello.grpc.pb.h"

using grpc::Channel;
using grpc::ClientContext;
using grpc::Status;

class HelloClient {
public:
    HelloClient(std::shared_ptr<Channel> channel)
        : stub_(hello::HelloService::NewStub(channel)) {}

    std::string SayHello(const std::string& name) {
        hello::HelloRequest request;
        request.set_name(name);

        hello::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<hello::HelloService::Stub> stub_;
};

int main() {
    HelloClient client(
        grpc::CreateChannel("localhost:50051",
                             grpc::InsecureChannelCredentials()));

    std::cout << client.SayHello("gRPC C++") << std::endl;
    return 0;
}

编译并运行

bash 复制代码
# 单文件编译
g++ -std=c++11 main.cpp hello.pb.cc hello.grpc.pb.cc \
-o hello_client \
`pkg-config --cflags --libs grpc++ grpc protobuf` \
-lgrpc++_reflection \
-lpthread

# 运行
./hello_client

启动服务端,再运行客户端,你会看到:

复制代码
Hello, gRPC C++

写在最后

很多人学 gRPC,卡在"看懂文档,却不知道怎么落地"。

真正跑通一次 C++ 服务端和客户端,你会发现:

gRPC 并不神秘,它只是把"服务调用"这件事,做得更像工程,而不是脚本。

如果你正在做 分布式系统、微服务、基础设施,gRPC 值得你认真掌握。

相关推荐
qwepoilkjasd6 小时前
DMC发送M-SEARCH请求,DMR响应流程
后端
liulilittle6 小时前
XDP VNP虚拟以太网关(章节:一)
linux·服务器·开发语言·网络·c++·通信·xdp
心在飞扬6 小时前
langchain学习总结:Python + OpenAI 原生 SDK 实现记忆功能
后端
张志鹏PHP全栈6 小时前
Solidity智能合约快速入门
后端
ihgry6 小时前
SpringCloud_Nacos
后端
我是Superman丶6 小时前
【异常】Spring Ai Alibaba 流式输出卡住无响应的问题
java·后端·spring
Ralph_Y6 小时前
多重继承与虚继承
开发语言·c++
bkspiderx7 小时前
C++虚析构函数:多态场景下的资源安全保障
c++·析构函数·虚函数表·虚析构函数
Delroy7 小时前
一个不懂MCP的开发使用vibe coding开发一个MCP
前端·后端·vibecoding
乌日尼乐7 小时前
【Java基础整理】Java多线程
java·后端