作者: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 将更好地满足用户需求的更详细的原因:
注意:用于 C#的 Google.Protobuf 库已经完全用 C#编写(没有原生组件),所以有一个纯粹的 gRPC C#实现就完全摆脱了开发者微服务栈中的原生组件。
用 C#开发 gRPC 的两个实现并不是免费的。它花费了宝贵的资源,我们相信工程时间应该花在让 C#中的 gRPC 更容易使用和添加新功能(当然还有修复 bug)上,而不是需要在两个不同的代码库上工作,它们都服务于同一个目的。另外,拥有两个独立的实现必然会在一定程度上分割用户基础,并将贡献者的工作分成两部分。同样,仅仅是用户需要选择他们想押注的两个实现中的哪一个的简单行为就会带来不确定性和内在风险(我们不希望我们的用户有这样的风险)。
通过使 grpc-dotnet 成为推荐的实现,通过使 Grpc.Core 的实现“仅限维护”(并最终将其淘汰),我们想实现以下目标:
从现在开始,我们将不再为 Grpc.Core 提供新特性或增强。重要的错误和安全问题将继续以正常的方式解决。
我们将正常发布 Grpc.Core 版本,以通常的 6 周节奏发布。
新版本将基于最新的 grpc C 核心原生库构建,所以所有不需要 C#特定工作的新特性也将被包括在内。
一旦达到这一里程碑,Grpc.Core 将不再被官方支持,所有用户将强烈建议从那时开始只使用 grpc-dotnet。
Grpc.Core nuget 包将继续在 nuget.org 仓库中可用,但不会提供更多的修复(=甚至没有安全修复)。
这两个包将继续得到完全支持,因为严格来说它们不是 Grpc.Core 的一部分,他们也被 grpc-dotnet 使用。
我们将继续支持 Grpc.Core(有关详细信息,请参阅弃用时间表),如果你想在未来继续获得更新和 bug 修复,你必须将你的项目迁移到 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。
我们强烈建议在新项目中只使用 grpc-dotnet。我们将在未来停止支持 Grpc.Core。
不,Grpc.Core 将继续支持一段时间(参见弃用时间表)。你应该有足够的时间来评估情况并计划迁移。
这种弃用目前不会影响谷歌云客户端库的现有用户。
因为 Grpc.Core 是客户端库的组成部分,Grpc.Core 的安全和 bug 修复将继续在谷歌云客户端库提供。
将提供扩展支持的客户端库:
注意 Grpc.Core 的扩展支持将只提供给当 Grpc.Core 用作这些客户端库的一部分时。对于谷歌云客户端库之外的其他用例,Grpc.Core 将不会在弃用日期之后得到官方支持,用户必须在弃用发生之前将现有工作负载迁移到 grpc-dotnet。
我们在github 上的文档[9]对支持的特性进行了比较。
我们欢迎你的反馈!通过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/