c++ grpc使用方法 c++如何实现grpc服务

酷雪小哥_3982

酷雪小哥_3982

2026-03-21

720人浏览

原创

grpc c++服务端需持住serverbuilder::buildandstart()返回的std::unique_ptr并调用server->wait()阻塞主线程,避免服务退出;流式响应须设超时、定期检查iscancelled()、显式finish(),防止卡死和资源泄漏。

c++ grpc使用方法 c++如何实现grpc服务

gRPC C++ 服务端怎么写最不容易崩

直接上手写 ServerBuilder 和 RegisterService 很容易漏掉线程模型和生命周期管理,导致服务启动后立刻挂或响应卡死。核心是:服务实例必须常驻、ServerBuilder::BuildAndStart() 返回的 std::unique_ptr<server></server> 必须持有住,否则构造完就析构,服务直接退出。

常见错误现象:ServerBuilder::BuildAndStart() 返回后进程静默退出;客户端连不上,telnet localhost 50051 显示连接拒绝;日志里没报错但根本没监听端口。

  • 用 std::unique_ptr<server></server> 持有返回值,别让它在作用域结束时被销毁
  • 调用 server->Wait() 阻塞主线程——这是让服务持续运行的必要操作,不是可选的“等一等”
  • 不要在 Service 子类里做耗时同步操作(比如读大文件、调外部 HTTP),会阻塞整个 gRPC 线程池;真要这么做,用 ThreadPool 或 std::async 脱离 gRPC 线程上下文
  • 如果用了自定义 CompletionQueue,确保它被正确 Shutdown(),否则程序无法退出

proto 文件生成 C++ 代码要注意哪些坑

protoc 生成的 C++ 文件依赖 gRPC 和 Protocol Buffers 的 C++ 运行时头文件,路径和链接顺序不对,编译直接报一堆 undefined reference to grpc::... 或 ‘google::protobuf::Message’ has no member named ‘SerializeWithCachedSizes’。

使用场景:你改了 service.proto,想重新生成 service.pb.h 和 service.grpc.pb.h,但 make 报错。

  • 确保 protoc 版本和链接的 libgrpc / libprotobuf 版本一致;混用 1.50 和 1.60 会触发 ABI 不兼容
  • 生成命令必须带 --grpc_out 和 --cpp_out,且都指定 --plugin=protoc-gen-grpc= 路径(新版 gRPC 不再默认内置插件)
  • CMake 中要用 find_package(gRPC REQUIRED),而不是手动加 -I;否则 #include <grpcpp></grpcpp> 找不到
  • 生成的 *.grpc.pb.h 里会包含 class ServiceName::AsyncService,这个类不能直接 new —— 它由 gRPC 内部管理,只用于注册到 ServerBuilder

客户端调用失败,错误信息是 UNAVAILABLE: failed to connect to all addresses

这几乎不是网络问题,而是客户端没正确配置 Channel。gRPC C++ 默认用 DNS 解析地址,localhost:50051 在某些环境(如容器、WSL)下会被解析成 IPv6 地址,而服务端只监听了 IPv4,连接就必然失败。

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载

性能影响:用 grpc::InsecureChannelCredentials() 是常规做法,但若误传 grpc::ChannelArguments() 里没设对参数,Channel 可能静默降级为非健康状态,重试逻辑失效。

  • 强制走 IPv4:用 grpc::CreateChannel("ipv4:127.0.0.1:50051", ...),别用 localhost
  • 检查服务端是否真在监听:ss -tlnp | grep 50051 或 lsof -i :50051,确认是 LISTEN 状态且 PID 对应你的进程
  • 客户端创建 Channel 后,建议立即调用 channel->GetState(true) 触发连接,并轮询 channel->WaitForStateChange() 确认变成 GRPC_CHANNEL_READY
  • 别复用已 Shutdown() 的 Channel;它的内部状态不可恢复,继续用会返回 UNAVAILABLE

如何让 C++ gRPC 支持流式响应但不卡死

用 ServerWriter<response></response> 发送多个响应时,如果没控制好发送节奏或没处理好客户端断连,服务端会卡在 Write() 调用上,甚至拖垮整个线程池。

原因在于 gRPC C++ 的流式 API 默认是同步阻塞的,而且底层 TCP 缓冲区满、客户端崩溃未发 RST、网络闪断等情况,都会让 Write() 无限期等待。

  • 给 ServerWriter 设置超时:context->set_deadline(std::chrono::system_clock::now() + std::chrono::seconds(30))
  • 调用 Write() 后,用 writer.Finish() 显式结束流;不 Finish,客户端可能永远收不到 EOF
  • 如果流式响应逻辑本身是异步的(比如从 Kafka 拉消息),别把回调直接塞进 ServerWriter::Write() —— 它不是线程安全的,必须保证同一 ServerWriter 实例只被一个线程调用
  • 客户端断连时,ServerContext::IsCancelled() 会变 true,循环中应定期检查并主动 break,避免无意义等待

最麻烦的其实是流式场景下的错误传播:一次 Write() 失败不会自动终止流,后续调用仍可能成功或失败,得靠你自己判断状态、清理资源。这点很容易被忽略,结果就是内存泄漏加连接堆积。

C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!

相关文章

c++速学教程(入门到精通)
c++速学教程(入门到精通)

c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
kafka消费者组有什么作用
kafka消费者组有什么作用

kafka消费者组的作用:1、负载均衡;2、容错性;3、广播模式;4、灵活性;5、自动故障转移和领导者选举;6、动态扩展性;7、顺序保证;8、数据压缩;9、事务性支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.01.12

2526

5

kafka消费组的作用是什么
kafka消费组的作用是什么

kafka消费组的作用:1、负载均衡;2、容错性;3、灵活性;4、高可用性;5、扩展性;6、顺序保证;7、数据压缩;8、事务性支持。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

590

5

rabbitmq和kafka有什么区别
rabbitmq和kafka有什么区别

rabbitmq和kafka的区别:1、语言与平台;2、消息传递模型;3、可靠性;4、性能与吞吐量;5、集群与负载均衡;6、消费模型;7、用途与场景;8、社区与生态系统;9、监控与管理;10、其他特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2024.02.23

564

5

Java 流式处理与 Apache Kafka 实战
Java 流式处理与 Apache Kafka 实战

本专题专注讲解 Java 在流式数据处理与消息队列系统中的应用,系统讲解 Apache Kafka 的基础概念、生产者与消费者模型、Kafka Streams 与 KSQL 流式处理框架、实时数据分析与监控,结合实际业务场景,帮助开发者构建 高吞吐量、低延迟的实时数据流管道,实现高效的数据流转与处理。

2026.02.04

610

32

java中break的作用
java中break的作用

本专题整合了java中break的用法教程,阅读专题下面的文章了解更多详细内容。

2025.10.15

2480

7

java break和continue
java break和continue

本专题整合了java break和continue的区别相关内容,阅读专题下面的文章了解更多详细内容。

2025.10.24

727

6

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

2023.07.18

5287

5

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

2023.08.10

2328

6

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

2024.01.03

3596

7

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Conan 2 Essentials 免费课程
Conan 2 Essentials 免费课程

共0课时 | 0人学习

CMake 与 Conan 集成实践
CMake 与 Conan 集成实践

共0课时 | 0人学习

Conan 2 高级依赖模型介绍
Conan 2 高级依赖模型介绍

共0课时 | 0人学习