grpc

框架

grpc/grpc

Google 开发的高性能 RPC 框架,支持多语言。

项目简介

gRPC 是 Google 开源的现代高性能 RPC 框架,基于 HTTP/2 协议和 Protocol Buffers 序列化。支持多语言跨平台通信,提供流式传输、认证和负载均衡等特性。

README 预览

# gRPC – An RPC library and framework\n\ngRPC is a modern, open source, high-performance remote procedure call (RPC)\nframework that can run anywhere. gRPC enables client and server applications to\ncommunicate transparently, and simplifies the building of connected systems.\n\n\n  \n    Homepage:\n    grpc.io\n  \n  \n    Mailing List:\n    grpc-io@googlegroups.com\n  \n\n\n[](https://gitter.im/grpc/grpc?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)\n\n## To start using gRPC\n\nTo maximize usability, gRPC supports the standard method for adding dependencies\nto a user's chosen language (if there is one). In most languages, the gRPC\nruntime comes as a package available in a user's language package manager.\n\nFor instructions on how to use the language-specific gRPC runtime for a project,\nplease refer to these documents\n\n-   [C++](src/cpp): follow the instructions under the `src/cpp` directory\n-   [C#/.NET](https://github.com/grpc/grpc-dotnet): NuGet packages\n    `Grpc.Net.Client`, `Grpc.AspNetCore.Server`\n-   [Dart](https://github.com/grpc/grpc-dart): pub package `grpc`\n-   [Go](https://github.com/grpc/grpc-go): `go get google.golang.org/grpc`\n-   [Java](https://github.com/grpc/grpc-java): Use JARs from Maven Central\n    Repository\n-   [Kotlin](https://github.com/grpc/grpc-kotlin): Use JARs from Maven Central\n    Repository\n-   [Node](https://github.com/grpc/grpc-node): `npm install @grpc/grpc-js`\n-   [Objective-C](src/objective-c): Add `gRPC-ProtoRPC` dependency to podspec\n-   [PHP](src/php): `pecl install grpc`\n-   [Python](src/python/grpcio): `pip install grpcio`\n-   [Ruby](src/ruby): `gem install grpc`\n-   [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions\n\nPer-language quickstart guides and tutorials can be found in the\n[documentation section on the grpc.io website](https://grpc.io/docs/). Code\nexamples are available in the [examples](examples) directory.\n\nPrecompiled bleeding-edge p

常见问题 (5)

故障排除
当客户端无法连接到服务器时,如何修复 gRPC C++ 中出现的 Abseil "Potential Mutex deadlock" 中止错误?

这是由 gRPC 的 TCP 连接握手器中的锁顺序反转引起的:TCPConnectHandshaker::FinishLocked() 在持有 TCPConnectHandshaker::mu_ 的情况下调用握手完成回调,而在连接失败、重试或关闭期间,可能会以不一致的顺序获取 HandshakeManager::mu_。随后,Abseil 的调试死锁检测器会调用 abort()。

永久修复方案:使用包含 PR #43184 的 gRPC 发布版本,或在构建 gRPC 时 cherry-pick 该 PR。该 PR 在 TCPConnectHandshaker::mu_ 临界区之外调用 InvokeOnHandshakeDone。

临时解决方法:在使用 gRPC 之前,将 Abseil 死锁检测初始化为报告模式而非中止模式:

#include "absl/synchronization/mutex.h"

absl::SetMutexDeadlockDetectionMode(absl::OnDeadlockCycle::kReport);

或者,以与 gRPC 相同的 release 配置构建 Abseil,例如使用 -DCMAKE_BUILD_TYPE=Release,这样会定义 NDEBUG,从而禁用仅在调试模式下的死锁检查。建议优先升级/修补 gRPC,因为该检测器识别出的是真实的锁顺序反转。

来源 Issue #40390
故障排除
如何修复 macOS 上因 "Too many open files" 或 "Failed accept4" 导致的 gRPC 压力测试失败?

在运行压力测试之前,提高 shell 的打开文件描述符限制:

ulimit -n 8192
build/client_channel_stress_test

在运行 thread_stress_test 或其他受影响的 gRPC 测试之前,使用相同的命令。使用 ulimit -n 验证该设置。当测试耗尽默认的文件描述符限制时会发生此故障,尤其是在高核心数的机器上。

来源 Issue #21728
故障排除
如何修复使用 OpenSSL 4.0 时的 gRPC 构建错误(C2440:无法从 'const X509_NAME *' 转换为 'X509_NAME *')?

gRPC 在针对 OpenSSL 4.0 进行编译时失败,因为 X509_get_subject_name() 现在返回 const X509_NAME*,导致 src/core/tsi/ssl_transport_security.cc、ssl_transport_security_utils.cc 和 grpc_tls_crl_provider.cc 中出现 "conversion loses qualifiers" 错误。修复方法:升级到包含 commit fb056ab0bb3ed003febe82f069ff41514288a4f3 的 gRPC 版本(OpenSSL 4 编译支持,PR #41932)。对于较旧的版本(例如 1.76.0),请修补源代码:将 subject_name 声明为 const X509_NAME*,并在将其传递给 X509_NAME_get_index_by_NID、X509_NAME_get_entry 和 X509_NAME_print_ex 时使用 const_cast<X509_NAME*>(...) 进行包装。注意:gRPC 对 OpenSSL 4 的支持被视为实验性的。

来源 Issue #42020
故障排除
如何修复 gRPC C++ 客户端在连接握手期间 TCPConnectHandshaker 中发生的 SIGABRT 死锁?

这是由 HandshakeManager::mu_ 和 TCPConnectHandshaker::mu_ 之间的锁反转(lock inversion)引起的。在连接失败、重试或关闭时,TCPConnectHandshaker::FinishLocked() 会在仍持有 TCPConnectHandshaker::mu_ 的情况下调用握手完成回调,当该回调重新进入 HandshakeManager 时可能会发生死锁。

修复方法:
1. 将 gRPC 升级到包含 PR [#43184](https://github.com/grpc/grpc/pull/43184) 的版本。
2. 如果无法立即升级,请应用该 PR 并从源码构建 gRPC:

git clone https://github.com/grpc/grpc.git
   cd grpc
   git fetch origin pull/43184/head:fix-tcp-handshake-deadlock
   git checkout fix-tcp-handshake-deadlock
   cmake -S . -B build -DgRPC_INSTALL=ON
   cmake --build build --target install

3. 基于打过补丁的 gRPC 库重新构建你的客户端。

该补丁在互斥锁作用域之外执行 InvokeOnHandshakeDone,从而打破死锁循环。作为临时缓解措施,可以减少长时间空闲连接的断开,并避免重复创建多个指向同一地址的 channel,但升级或打补丁才是可靠的修复方法。该问题报告于 gRPC 1.69、RHEL 9.x 和 GCC 11.4.1 环境。

来源 Issue #40378
故障排除
如何修复 gRPC C++ 针对不支持的 grpc-encoding 标头返回"Stream removed"或 INTERNAL_ERROR 的问题?

将 gRPC C++ 升级到包含针对 issue #36770 的 PR "[Core] Fix compression error handling edge cases" 的发布版本,或从包含该修复的提交进行构建。修正后的行为如下:客户端从服务器接收到不支持的编码时返回 INTERNAL;服务器从客户端接收到不支持的编码时返回 UNIMPLEMENTED,而不再以 RST_STREAM INTERNAL_ERROR 重置 HTTP/2 流;在未协商任何非 identity 编码的情况下,envelope 压缩位被置位的消息将以 INTERNAL 失败,而不再被忽略。作为变通方案,请确保通信双方仅通告彼此都支持的压缩算法,并且除非已为该流协商了非 identity 编码,否则不要设置压缩消息位。

来源 Issue #36770