作者:Jan Tattermusch
grpc-dotnet(Grpc.Net.Client[1]和Grpc.AspNetCore.Server[2] nuget 包)现在是.NET/C#中推荐的 gRPC 实现。最初的 gRPC C#实现(Grpc.Core nuget 包)将进入维护模式,不会得到任何新功能,只会收到重要的错误修复和安全修复。最终的计划是在未来的某个时候逐步完全淘汰 Grpc.Core。该公告描述了我们决定这样做的原因,并更详细地列出了该计划。
2019 年 9 月,我们宣布[3]了一个新的gRPC C#实现[4]的普遍可用性,它不再基于 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#实现[5](通常称为“gRPC.Core”,它的 nuget 包的名字)肯定有它的位置,它是非常受欢迎的,我们现在正接近一个点,在 2016 年(当 gRPC C#作为 GA 发布时)的一些设计决定不再有他们过去的重量。例如,我们决定将 gRPC C#实现建立在一个原生库上,因为在 2016 年,还没有可用的 C# HTTP/2 库可供我们依赖。通过依赖 C 核心原生库,我们能够更快地交付一个稳定的、高性能的 gRPC 库,而不是从头开始用 C#实现所有东西。但是从今天的角度来看,采用原生依赖已经没有多大意义了,因为 HTTP/2 支持已经内置到.NET Core 框架中。拥有原生依赖的好处正在减少,而拥有一个原生依赖的维护负担却保持不变。
在这两种稳定的 C#实现中,grpc-dotnet 实现无疑是未来潜力更大的一个。它是一个更现代的实现,与.NET 的现代版本很好地集成在一起,而且它很可能与 C#社区在几年后的发展方向更加一致。它也是一个纯粹的 C#实现(没有原生组件),这使得它对贡献更加友好,带来更好的可调试性,这也是 C#爱好者喜欢看到的东西。
因为为 C#提供两种官方的 gRPC 实现的维护成本非同小可,而且从长远来看 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 核心服务 API 和 HTTP2 客户端),它是用纯 C#实现的,代码对 C#开发人员更容易访问(对只想了解事情如何工作的用户和可能编写 PR 的贡献者)。grpc-dotnet 代码库相对较小,构建只需几秒钟,运行测试简单快捷。从长远来看,更轻松的开发和贡献友好性应弥补当今缺少的一些功能,并使其成为用户的绝佳选择——也就是说,降低贡献和修复/改进产品的障碍将转化为更多的产品修复,并在一段时间后改善用户体验。
- 与依赖于原生组件的实现相比,使用纯 C#实现的库通常更受.NET 社区的欢迎。虽然 C#很好地支持与原生库的互操作,但这是一种大多数 C#开发人员不熟悉的技术,对他们来说它就像一个黑盒。原生互操作很难正确实现,而且有许多缺点(例如,更复杂的开发和构建过程、复杂的调试、难以维护、难以获得社区贡献、难以为多个平台提供支持)。使用 Grpc.Core 我们能够克服这些挑战中的大多数(所以这些天事情都很顺利),但这需要大量的努力,解决方案有时是复杂和脆弱的,维护它是昂贵的,需要大量的专业知识。
注意:用于 C#的 Google.Protobuf 库已经完全用 C#编写(没有原生组件),所以有一个纯粹的 gRPC C#实现就完全摆脱了开发者微服务栈中的原生组件。
为什么不永远保留 Grpc.Core 呢?
用 C#开发 gRPC 的两个实现并不是免费的。它花费了宝贵的资源,我们相信工程时间应该花在让 C#中的 gRPC 更容易使用和添加新功能(当然还有修复 bug)上,而不是需要在两个不同的代码库上工作,它们都服务于同一个目的。另外,拥有两个独立的实现必然会在一定程度上分割用户基础,并将贡献者的工作分成两部分。同样,仅仅是用户需要选择他们想押注的两个实现中的哪一个的简单行为就会带来不确定性和内在风险(我们不希望我们的用户有这样的风险)。
通过使 grpc-dotnet 成为推荐的实现,通过使 Grpc.Core 的实现“仅限维护”(并最终将其淘汰),我们想实现以下目标:
- 释放工程资源来开发更好的特性和可用性。
- 统一 gRPC C#用户群。这将导致将所有社区工作和贡献导向单一的实施。它还消除了用户需要选择使用这两种正式实现中的哪一种而产生的内在摩擦。
- 解决 Grpc.Core 的一些众所周知的痛点,很难通过其他方式解决的问题。
- 通过与.NET 社区保持一致,让 gRPC 的 C#/.NET 实现面向未来。
计划
阶段 1:Grpc.Core 变成“仅限维护”
时间:即刻生效(2021 年 5 月)
从现在开始,我们将不再为 Grpc.Core 提供新特性或增强。重要的错误和安全问题将继续以正常的方式解决。
我们将正常发布 Grpc.Core 版本,以通常的 6 周节奏发布。
新版本将基于最新的 grpc C 核心原生库构建,所以所有不需要 C#特定工作的新特性也将被包括在内。
阶段 2:Grpc.Core 变成“弃用”
时间:1 年后(2022 年 5 月)
一旦达到这一里程碑,Grpc.Core 将不再被官方支持,所有用户将强烈建议从那时开始只使用 grpc-dotnet。
Grpc.Core nuget 包将继续在 nuget.org 仓库中可用,但不会提供更多的修复(=甚至没有安全修复)。
Grpc.Tools 和 Grpc.Core.Api nuget 包的未来
这两个包将继续得到完全支持,因为严格来说它们不是 Grpc.Core 的一部分,他们也被 grpc-dotnet 使用。
- Grpc.Tools nuget 包为 C#项目提供 codegen 构建集成将继续得到支持(并有可能得到改进)——因为它被 Grpc.Core 和 grpc-dotnet 使用。此包独立于 C 内核。
- Grpc.Core.Api 包是 grpc-dotnet 的先决条件,因此它将有可能随着时间的推移而演变(但它是一个纯 C# API 包,因为它只包含公共 API 表面,更改是非常少的)。
常见问题
我现在是 Grpc.Core 用户,这对我意味着什么?
我们将继续支持 Grpc.Core(有关详细信息,请参阅弃用时间表),如果你想在未来继续获得更新和 bug 修复,你必须将你的项目迁移到 grpc-dotnet。
如何将现有项目迁移到 grpc-dotnet?
因为 Grpc.Core 和 grpc-dotnet 是两个不同的库,在你的项目中会有一些必要的代码更改。由于这两个实现都共享调用和处理 rpc 的相同 API(我们故意这样设计它们),我们相信必要的代码更改应该相当少。对于许多应用程序,你只需要改变配置 gRPC 通道和服务器的方式;这通常只是应用程序实现的一小部分,往往与业务逻辑分离。
更多关于如何从 Grpc.Core 迁移到 grpc-dotnet 的提示,请参见Migrating gRPC services from C-core to ASP.NET Core[6]。
我们计划在未来发布一个更详细的迁移指南,以帮助从 Grpc.Core 迁移到 grpc-dotnet。
我想在一个新项目中使用 C#的 gRPC。我应该选择哪种实现?
我们强烈建议在新项目中只使用 grpc-dotnet。我们将在未来停止支持 Grpc.Core。
这是否意味着我现在需要停止使用 Grpc.Core 吗?
不,Grpc.Core 将继续支持一段时间(参见弃用时间表)。你应该有足够的时间来评估情况并计划迁移。
我没有在我的代码中直接使用 gRPC,但我使用谷歌云客户端库(它在底层确实使用 Grpc.Core)。这对我有什么影响?
这种弃用目前不会影响谷歌云客户端库的现有用户。
因为 Grpc.Core 是客户端库的组成部分,Grpc.Core 的安全和 bug 修复将继续在谷歌云客户端库提供。
将提供扩展支持的客户端库:
- Google Cloud Libraries for .NET[7]
- Google Ads Client Library for .NET[8]
注意 Grpc.Core 的扩展支持将只提供给当 Grpc.Core 用作这些客户端库的一部分时。对于谷歌云客户端库之外的其他用例,Grpc.Core 将不会在弃用日期之后得到官方支持,用户必须在弃用发生之前将现有工作负载迁移到 grpc-dotnet。
我可以在哪里找到支持的特性列表?
我们在github 上的文档[9]对支持的特性进行了比较。
我有本文档没有涵盖的一个重要的 Grpc.Core 用例。
我们欢迎你的反馈!通过gRPC-io 谷歌群[10],或任何其他gRPC 社区的主要渠道[11]写给我们。
参考资料
[1]
Grpc.Net.Client: https://www.nuget.org/packages/Grpc.Net.Client/
[2]
Grpc.AspNetCore.Server: https://www.nuget.org/packages/Grpc.AspNetCore.Server/
[3]
宣布: https://www.grpc.io/blog/grpc-on-dotnetcore/
[4]
gRPC C#实现: https://github.com/grpc/grpc-dotnet
[5]
最初的 gRPC C#实现: https://github.com/grpc/grpc/tree/master/src/csharp
[6]
Migrating gRPC services from C-core to ASP.NET Core: https://docs.microsoft.com/en-us/aspnet/core/grpc/migration
[7]
Google Cloud Libraries for .NET: https://github.com/googleapis/google-cloud-dotnet
[8]
Google Ads Client Library for .NET: https://github.com/googleads/google-ads-dotnet/
[9]
github 上的文档: https://github.com/grpc/grpc-dotnet/blob/master/doc/implementation_comparison.md
[10]
gRPC-io 谷歌群: https://groups.google.com/forum/#!forum/grpc-io
[11]
gRPC 社区的主要渠道: https://www.grpc.io/community/