C# 中 gRPC 的未来属于 grpc-dotnet
2023年10月2日更新:`Grpc.Core` 的维护期再次延长,至少延长至 2024 年 10 月。有关 `Grpc.Core` 的最新信息,请参阅公告。
2022年5月3日更新:`Grpc.Core` 的维护期已延长至 2023 年 5 月。有关 `Grpc.Core` 未来的更多信息,请参阅公告。
摘要:grpc-dotnet(Grpc.Net.Client 和 Grpc.AspNetCore.Server NuGet 包)现已成为 .NET/C# 推荐的 gRPC 实现。原始的 gRPC C# 实现(Grpc.Core NuGet 包)将进入维护模式,不再获取任何新功能,今后仅接收重要的错误修复和安全修复。最终计划是在未来的某个时间彻底淘汰 Grpc.Core。本公告说明了我们做出此决定的原因,并详细介绍了相关计划。
2019 年 9 月,我们宣布了一种新的 gRPC C# 实现正式可用,它不再依赖于 gRPC C 核心原生库,而是使用 .NET Core 3 和 ASP.NET Core 3 中添加的 HTTP/2 协议实现。我们将此实现称为“grpc-dotnet”。
当我们引入 grpc-dotnet 实现时,我们宣布这两种 gRPC C# 实现(新的纯 C# grpc-dotnet 实现和基于 C 核心原生库的原始 gRPC C# 实现)将共存,让用户选择最适合他们的实现。这在当时是非常合理的,因为 grpc-dotnet 当时还是全新的,并且需要刚发布的 .NET Core 框架,而原始的 gRPC C# 实现已经稳定了很长时间,拥有大量用户,并且可以在非常旧的 .NET Framework 版本上运行。情况需要一些时间来沉淀。
自那时起,新的 grpc-dotnet 实现取得了长足进步:它已被许多用户采用并变得非常流行,已被许多生产环境中的应用程序使用,并且还添加了许多有趣的新功能。此外,它的主要先决条件——.NET Core 3 框架,已经存在一段时间了,其采用率也在不断增长。
同时,虽然原始 gRPC C# 实现(通常称为“Grpc.Core”,即其 NuGet 包的名称)确实占有一席之地并且非常受欢迎,但我们现在正接近一个临界点,即 2016 年(gRPC C# 作为 GA 发布时)所做的某些设计决策已不再具有当初的重要性。例如,我们决定将 gRPC C# 实现建立在原生库上,因为在 2016 年,没有我们可以依赖的可用 C# HTTP/2 库。通过依赖 C 核心原生库,我们能够比从零开始用 C# 实现一切更快地交付稳定、高性能的 gRPC 库。但从今天的角度来看,由于 HTTP/2 支持现在已内置于 .NET Core 框架中,进行原生依赖已不再那么有意义。拥有原生依赖的好处正在减少,而维护它的负担却依然存在。
在两种稳定的 C# 实现中,grpc-dotnet 实现绝对是更具未来潜力的一个。它是一个更现代的实现,与现代版本的 .NET 集成良好,并且很可能与 C# 社区几年后的发展方向更加一致。它也是一个纯 C# 实现(没有原生组件),这使得它更便于贡献,具有更好的可调试性,而且这正是 C# 爱好者乐于看到的。
由于维护两个官方的 gRPC C# 实现的成本并不低,而且从长远来看,grpc-dotnet 对所有用户来说似乎都是最佳选择,因此我们宣布计划淘汰原始的 gRPC C# 实现(NuGet 包 Grpc.Core),转而支持更现代、更有前景的 grpc-dotnet 实现。
该计划的细节在以下章节中进行了描述,并进一步解释了其合理性。为了帮助理解淘汰 Grpc.Core 的决定的后果,我们还整理了一份常见问题列表并提供了答案。
是什么让 grpc-dotnet 成为首选实现
简而言之,grpc-dotnet 似乎是未来的更好选择。一些最重要的要点已经提到过。以下是我们认为 grpc-dotnet 能更好地满足用户需求的详细理由列表:
它是一个更现代的实现,基于最新版本 .NET 框架的功能。因此,它很可能在未来成为两种实现中更具可行性的一个。
它与 C# / .NET 社区的现状和未来更加一致。保持与社区的发展方向一致似乎是 C# 中 gRPC 未来的最佳赌注。
该实现更加敏捷且便于贡献——因为它在内部基于众所周知的原语 / API(ASP.NET Core 服务 API 和 HTTP/2 客户端),并且是用纯 C# 实现的,因此代码对于 C# 开发人员来说更容易理解(无论是对于只想了解其工作原理的用户,还是对于可能会提交 PR 的潜在贡献者)。grpc-dotnet 代码库相对较小,构建只需几秒钟,运行测试既简单又快速。从长远来看,更便捷的开发和贡献友好性应该会弥补目前缺失的一些功能,并使其成为用户的卓越选择——也就是说,降低贡献和修复/改进内容的门槛,随着时间的推移会转化为更多的修复内容和更好的用户体验。
拥有一个纯 C# 实现的库是 .NET 社区普遍喜欢的,相比之下,依赖原生组件的实现则不然。虽然 C# 对与原生库的互操作有很好的支持,但这是大多数 C# 开发人员不熟悉的技巧,在他们看来就像一个黑盒。原生互操作很难做到完美,并且有很多缺点(例如更复杂的开发和构建过程、复杂的调试、难以维护、难以获得社区贡献、难以提供多平台支持)。使用 Grpc.Core,我们克服了其中大部分挑战(所以如今一切都能正常工作),但这付出了巨大的努力,解决方案有时既复杂又脆弱,维护成本高昂并且需要大量的专业知识。
注意:用于 C# 的 Google.Protobuf 库已经是纯 C# 编写(没有原生组件),因此拥有一个纯 C# 的 gRPC 实现可以完全从开发人员的微服务堆栈中移除原生组件。
为什么不永远保留 Grpc.Core?
开发两种 gRPC C# 实现并非免费。它消耗宝贵的资源,我们认为将工程时间花在使 C# 中的 gRPC 更易于使用和添加新功能(当然还有修复错误)上,而不是花在维护两个用途相同的不同代码库上会更好。此外,拥有两个独立的实现必然会在一定程度上分散用户群,并将贡献者的努力一分为二。而且,仅仅是用户需要选择他们想要依赖哪种实现这一行为,就带有不确定性和固有的风险(这些都不是我们希望用户承担的)。
通过将 grpc-dotnet 作为推荐实现,并将 Grpc.Core 实现设为“仅维护”(并最终淘汰它),我们旨在实现以下目标:
- 释放工程资源,用于开发更好的功能和提高易用性。
- 统一 gRPC C# 用户群。这将促使所有的社区工作和贡献都集中到一个单一的实现上。它还消除了因用户需要选择使用两种官方实现中的哪一种而产生的固有摩擦。
- 解决 Grpc.Core 一些难以通过其他方式解决的众所周知的痛点。
- 通过与 .NET 社区保持一致,使 C#/.NET 的 gRPC 实现面向未来。
计划
第 1 阶段:Grpc.Core 变为“仅维护”
时间:即刻生效(2021 年 5 月)
从现在开始,我们将不再为 Grpc.Core 提供新功能或增强功能。重要的错误和安全问题将继续以正常方式处理。
我们将按常规发布 Grpc.Core 版本,遵循每 6 周一次的周期。
发布版本将基于最新的 gRPC C 核心原生库构建,因此所有不需要 C# 特定工作的各项新功能也将包含在内。
第 2 阶段:Grpc.Core 变为“已弃用”
时间:一年后(2022 年 5 月)
一旦达到此里程碑,Grpc.Core 将不再得到官方支持,强烈建议所有用户从此时起仅使用 grpc-dotnet。
Grpc.Core NuGet 包将保留在 nuget.org 存储库中,但不会再提供任何修复(= 甚至不包括安全修复)。
Grpc.Tools 和 Grpc.Core.Api NuGet 包的未来
这两个包将继续得到完全支持,因为严格来说它们不是 Grpc.Core 的一部分,它们也被 grpc-dotnet 使用。
- 为 C# 项目提供 codegen 构建集成的 Grpc.Tools NuGet 包将继续得到支持(并可能会得到改进)——因为它同时被 Grpc.Core 和 grpc-dotnet 使用。此包独立于 C 核心。
- Grpc.Core.Api 包是 grpc-dotnet 的先决条件,因此它可能会随时间演变(但它只是一个纯 C# API 包,并且因为它只包含公共 API 表面,所以变更非常少见)。
问与答
我是 Grpc.Core 的现有用户,这对意味着什么?
虽然我们将继续支持 Grpc.Core 一段时间(详情请参阅弃用时间表),但如果您希望在未来继续获得更新和错误修复,则必须将您的项目迁移到 grpc-dotnet。
如何将现有项目迁移到 grpc-dotnet?
由于 Grpc.Core 和 grpc-dotnet 是两个不同的库,因此您的项目中需要进行一些代码更改。由于这两种实现共享相同的 RPC 调用和处理 API(我们有意这样设计),我们认为所需的代码更改应该非常小。对于许多应用程序,您只需要更改配置 gRPC 通道和服务器的方式;这通常只是应用程序实现的一小部分,并且往往与业务逻辑分开。
有关如何从 Grpc.Core 迁移到 grpc-dotnet 的更多提示,请参阅将 gRPC 服务从 C-core 迁移到 ASP.NET Core。
我们计划在未来发布更详细的迁移指南,以促进从 Grpc.Core 到 grpc-dotnet 的迁移。
我想在 C# 的新项目中使用 gRPC。我应该选择哪种实现?
我们强烈建议新项目仅使用 grpc-dotnet。我们将来会停止对 Grpc.Core 的支持。
这意味着我现在需要停止使用 Grpc.Core 吗?
不需要,Grpc.Core 将继续支持一段时间(请参阅弃用时间表)。您应该有足够的时间来评估情况并规划您的迁移。
我不直接在代码中使用 gRPC,但我正在使用 Google Cloud 客户端库(它们在底层使用了 Grpc.Core)。这对我有何影响?
此弃用目前不会影响 Google Cloud 客户端库的现有用户。
由于 Grpc.Core 是这些客户端库不可或缺的一部分,因此将继续为 Google Cloud 客户端库提供 Grpc.Core 的安全和错误修复。
将提供扩展支持的客户端库:
请注意,Grpc.Core 的扩展支持仅在作为这些客户端库的一部分使用时才会提供。对于除 Google Cloud 客户端库之外的其他用例,Grpc.Core 在弃用日期之后将不会得到官方支持,用户必须在弃用发生之前将现有工作负载迁移到 grpc-dotnet。
我在哪里可以找到支持的功能列表?
我们的 GitHub 文档 中有支持功能的对比。
我有一个重要的 Grpc.Core 用例没有包含在本文件中。