C# 中 gRPC 的未来属于 grpc-dotnet
更新 2023-10-02: Grpc.Core
的维护期已再次延长,至少到 2024 年 10 月。请参阅公告 以获取关于 Grpc.Core
的最新信息。
更新 2022-05-03: 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 core 原生库,而是使用了在 .NET Core 3 和 ASP.NET Core 3 中添加的 HTTP/2 协议实现。我们将此实现称为“grpc-dotnet”。
在我们推出 grpc-dotnet 实现时,我们宣布两个 gRPC C# 实现(新的纯 C# grpc-dotnet 实现和基于 C core 原生库的原始 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 core 原生库,我们能够比从头开始用 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 社区的发展方向。与社区发展方向保持一致似乎是 gRPC 在 C# 中的未来最佳选择。
该实现更敏捷且更易于贡献——因为它内部基于众所周知的基础类型 / API(ASP.NET core 服务 API 和 HTTP2 客户端),并且是用纯 C# 实现的,代码对 C# 开发者来说更易于理解(无论是想了解其工作原理的用户还是潜在的贡献者,他们都可以提交 PR)。grpc-dotnet 代码库相对较小,构建只需几秒钟,运行测试简单快捷。从长远来看,更简单的开发和更友好的贡献环境应该能弥补目前缺少的一些功能,使其成为用户的更优选择——也就是说,降低贡献和修复/改进的门槛意味着在一段时间后将有更多内容得到修复和更好的用户体验。
与依赖原生组件的实现相比,用纯 C# 实现的库通常受到 .NET 社区的青睐。尽管 C# 对与原生库进行互操作有很好的支持,但这是一种大多数 C# 开发者不熟悉的技术,对他们来说就像一个黑盒子。原生互操作很难做到正确,并且有很多缺点(例如,更复杂的开发和构建过程、复杂的调试、难以维护、难以获得社区贡献、难以支持多种平台)。使用 Grpc.Core,我们能够克服大多数这些挑战(因此如今它能够正常工作),但这付出了很多努力,解决方案有时复杂且脆弱,维护成本高昂且需要大量专业知识。
注意:用于 C# 的 Google.Protobuf 库已经完全用纯 C# 编写(无原生组件),因此拥有一个纯 C# 的 gRPC 实现可以完全消除开发者微服务栈中的原生组件
为何不永远保留 Grpc.Core?
开发两个 gRPC C# 实现并非没有成本。它耗费宝贵的资源,我们认为工程师的时间最好花在使 gRPC 在 C# 中更容易使用以及添加新功能(当然还有修复错误)上,而不是需要在两个服务于相同目的的不同代码库上工作。此外,拥有两个独立的实现必然会在一定程度上分散用户群体,并将贡献者的精力分成两部分。另外,仅仅是用户需要选择他们想押注于哪个实现这一简单行为,也带来了不确定性和固有风险(这些都不是我们希望用户承受的)。
通过将 grpc-dotnet 作为推荐实现,并将 Grpc.Core 实现设为“仅维护”(并最终淘汰),我们旨在实现以下目标:
- 释放工程资源,以开发更好的功能和提升可用性。
- 统一 gRPC C# 用户群。这将引导所有社区工作和贡献集中到单一实现上。它还消除了用户需要选择使用两个官方实现中哪一个所导致的固有摩擦。
- 解决 Grpc.Core 一些众所周知的痛点,这些痛点通过其他方式很难解决。
- 通过与 .NET 社区保持一致,使 gRPC 在 C#/.NET 中的实现面向未来。
计划
阶段 1:Grpc.Core 进入“仅维护”阶段
时间:即时生效(2021 年 5 月)
从现在起,我们将不再为 Grpc.Core 提供新功能或增强。重要的错误和安全问题将继续以正常方式解决。
我们将正常发布 Grpc.Core 版本,保持通常的每 6 周发布频率。
这些版本将基于最新的 grpc C core 原生库构建,因此所有不需要 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 core。
- Grpc.Core.Api 包是 grpc-dotnet 的一个先决条件,因此它也可能随着时间而演进(但它是一个纯 C# API 的包,并且由于它只包含公共 API surface,所以变化非常不频繁)。
问答
我是当前的 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 是这些客户端库不可或缺的一部分,因此 Grpc.Core 的安全更新和错误修复将继续为 Google Cloud 客户端库提供。
将提供扩展支持的客户端库
请注意,仅当 Grpc.Core 作为这些客户端库的一部分使用时,才会为其提供扩展支持。对于 Google Cloud 客户端库之外的其他用例,Grpc.Core 在弃用日期之后将不再获得官方支持,并且用户必须在弃用发生之前将现有工作负载迁移到 grpc-dotnet。
我可以在哪里找到支持的功能列表?
我们的 GitHub 文档提供了支持功能的比较。
我有一个本文档未涵盖的重要 Grpc.Core 用例。