> ## Content Index
> Fetch the complete content index at: https://huizhou92.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 【译】gRPC:坏的部分
- URL: https://huizhou92.com/e8-af-91grpc-e5-9d-8f-e7-9a-84-e9-83-a8-e5-88-86/
- Published: 2024-07-17T01:35:37.000Z
- Updated: 2026-09-06T11:40:29.000Z
- Description: 本文译文深入剖析了gRPC这款高性能RPC框架的不足，详细讨论了其陡峭的学习曲线、过度复杂的接口设计、不完善的HTTP/2兼容性、延迟的HTTP/3支持、JSON映射局限及大消息处理难题，帮助开发者全面认识并探讨gRPC优化改进的可能方向。
- Author: huizhou92
- Tags: tech, golang, grpc, #lang-zh-cn

原文链接🔗: [https://kmcd.dev/posts/grpc-the-bad-parts/](https://kmcd.dev/posts/grpc-the-bad-parts/?ref=huizhou92.com)

gRPC 作为一款高性能的 RPC 框架，在 Google 内部取得了巨大成功，并显著改变了我们部署 API 的方式。然而，它并非完美无缺。创建一个支持代码生成和多语言的 RPC 框架，必然会面临诸多挑战。笔者使用 gRPC 已近十年，在此有必要反思其有待改进之处。

## **学习曲线：术语与复杂性**

首先，我们从一些细节入手。“一元请求”（Unary Request）是指客户端向服务器发送单个请求并接收单个响应的调用。为何 gRPC 必须使用如此晦涩的术语？每次使用都需解释，实在令人困扰。  
![](https://kmcd.dev/posts/grpc-the-bad-parts/meme.png)

说到一元请求，gRPC 的实现也显得过于复杂。尽管 gRPC 的流式接口功能强大，但对于简单的 RPC 调用，它引入了不必要的复杂性。这增加了调试 gRPC 调用的难度，因为即使是一元请求也需要分帧，这本是流式传输的特性。Protobuf 编码已足够复杂，无需在非必要之处增加额外的 gRPC 分帧。此外，对于 Web API 而言，使用 cURL 示例来解释 gRPC 的使用方式非常困难。“需要启用服务器反射吗？”这句话我已说过无数次。

这种复杂性也体现在工具层面，尤其是强制的代码生成步骤。对于重视运行时灵活性的动态语言而言，这可能是一个障碍。此外，一些开发者可能会对需要额外构建步骤的技术望而却步。现代 Web 开发已包含众多构建步骤，再增加一个往往令人犹豫。

## **Web 兼容性：HTTP/2 与 HTTP/3**

对 HTTP/2 的依赖最初限制了 gRPC 的普及，因为并非所有平台和浏览器都完全支持它。尽管情况有所改善，但在某些环境下仍是挑战。即使支持 HTTP/2，浏览器也缺乏处理 HTTP Trailers 的能力，因此目前浏览器仍无法“原生”使用 gRPC。gRPC-Web 通过避免使用 Trailers 解决了这个问题，但通常需要额外的代理支持，这非常麻烦。

延迟采用 HTTP/3 协议可能阻碍了 gRPC 充分利用其性能和效率优势。笔者深受 HTTP/2 的“[队头阻塞”](https://http3-explained.haxx.se/en/why-quic/why-tcphol?ref=huizhou92.com)（Head-of-line blocking）问题困扰，而 HTTP/3 本可彻底解决这一问题。一个大力推广 HTTP/2 的框架，却在 HTTP/3 支持上如此挣扎，着实令人费解。

## **JSON 映射与 Prototext：标准化缺失**

早期缺乏标准化的 `JSON` 映射是另一个失误。这使得习惯于 JSON API 的开发者难以接受 `gRPC`，我认为 `gRPC` 从未摆脱这种负面印象。Protobuf 类型与 JSON 之间的映射简化了与现有工具和系统的集成与互操作。当你说“是的，这是一种高效的二进制格式……但如果你想调试，可以设置这个标志来返回 JSON”时，Web 开发者会非常高兴。总之，现在 Protobuf 已有标准的 JSON 映射规则（以及反向），而 Protobuf 文本格式（Prototext）则显得多余。既然有了 JSON，文本格式便不再必要。不如将其废弃。如果大家同意，我愿意假装它从未存在过。

## **消息大小限制：分块的必要性**

大多数 Protobuf 编码器/解码器都期望完全解析整个消息，然后将完整响应提供给消费者，但内存有限，有时我们需要处理更大的消息。有时，我们希望将这些大消息分段传输到其他地方，而不是将其全部保存在内存中。

因此，如果需要上传大型文件，我们需要实现某种文件分块机制。尽管分块是处理大文件的合理方案，但 gRPC 缺乏标准化的方法，可能导致实现不一致，增加开发工作量。

例如，以下是使用 gRPC 上传文件的示例：

```protobuf
syntax = "proto3";

package file_service;

service FileService {
  rpc Upload(stream UploadRequest) returns(UploadResponse);
}

message UploadRequest {
  string file_name = 1;
  bytes chunk = 2;
}

message UploadResponse {
  string etag = 1;
}

```

这既是 Protobuf 的优势，也是劣势。在 Protobuf 中定义这个概念非常容易，但实际实现却可能繁琐且容易出错。尽管 gRPC 的创建者 Google 已为其 API 找到了解决方案，但缺乏标准化的方法，让其他人需要重复造轮子。

你可能会想：“Google 在其大多数 API 中使用 gRPC，显然他们已经解决了这个问题。” 你是对的。他们确实有一个 gRPC 和 HTTP 版本用于下载（可能很大的）文件。我们可以直接比较 [gRPC](https://github.com/googleapis/google-cloud-go/blob/v0.114.0/storage/grpc%5Fclient.go?ref=huizhou92.com#L996-L1152)和[HTTP](https://github.com/googleapis/google-cloud-go/blob/v0.114.0/storage/http%5Fclient.go?ref=huizhou92.com#L888-L911)版本，gRPC 版本明显更复杂。

## **社区活跃度：依赖管理之殇**

我发现 gRPC/Protobuf 社区的活跃度不高。一些网站缺乏明显的活动，可能会让人觉得 gRPC 停滞不前或维护不力。这可能会阻碍潜在的采用者，并减缓社区的增长。这可能是因为选择太多，导致人们难以在 GitHub 问题之外找到愿意讨论 gRPC 的人。

很长一段时间里，每当看到一个代码库使用 Protobuf，我都会发现一个奇怪的脚本，用于下载随机的 Protobuf 文件，以高度自定义的方式放置它们，并执行一系列极其复杂的 `protoc` 调用。只有 Google 才会认为不解决依赖管理问题就是解决依赖管理问题。Google 有自己的依赖管理方式，我们只能望其项背。

## **持续改进：未来可期**

尽管我对 gRPC 提出了批评，但我希望这些评论是建设性的。读到这里的人应该知道，许多问题已经或正在得到解决：

- 一些 gRPC 实现已支持 HTTP/3。ConnectRPC 让使用 HTTP/3 的 gRPC 变得非常容易。
- 由于 Protobuf 规范已包含[标准的JSON 映射](https://protobuf.dev/programming-guides/proto3/?ref=huizhou92.com#json)，我不再需要担心文本格式。
- 如果你知道去哪里寻找，gRPC 社区其实非常活跃。例如，[Buf Slack](https://buf.build/links/slack?ref=huizhou92.com) 是一个很好的资源。
- [Buf CLI ](https://buf.build/docs/ecosystem/cli-overview?ref=huizhou92.com)是一款出色的 gRPC 工具。它完全取代了 `protoc`，并增加了 linting、破坏性变更检测、gRPC 版 cURL、与 Buf Schema Registry 的集成（真正的依赖管理！）等功能。此外，越来越多的工具开始支持 gRPC，例如 Postman、Insomnia 和 k6。

## 结论

尽管 gRPC 取得了不可否认的成功，但承认其不足之处至关重要，这有助于其持续发展和改进。通过解决学习曲线、兼容性、标准化和社区参与等方面的问题，我们可以释放 gRPC 的全部潜力，使其成为所有开发者都能轻松使用的工具

## 延伸阅读

[再谈 gRPC 的 Trailers 设计](https://taoshu.in/grpc-trailers.html?ref=huizhou92.com)

---

- [本文长期链接](https://huizhou92.com/e8-af-91grpc-e5-9d-8f-e7-9a-84-e9-83-a8-e5-88-86)
- 如果您觉得我的博客对你有帮助，请通过 [RSS](https://huizhou92.com/sitemap.xml)订阅我。
- 或者在[X](https://x.com/@piaopiaopig?ref=huizhou92.com)上关注我。
- 如果您有[Medium](https://medium.huizhou92.com/?ref=huizhou92.com)账号，能给我个关注嘛？我的文章第一时间都会发布在Medium。