C# 中 gRPC 的未来属于 grpc-dotnet
更新于 2023-10-02:`Grpc.Core` 的维护期再次延长,至少到 2024 年 10 月。请参阅公告以获取关于 `Grpc.Core` 的最新信息。
更新于 2022-05-03:`Grpc.Core` 的维护期已延长至 2023 年 5 月。请参阅公告以获取关于 `Grpc.Core` 未来发展的更多信息。
TL;DR(太长不看) 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 社区当前和未来的发展方向。与社区发展方向保持一致,似乎是 gRPC 在 C# 中未来发展的最佳选择。
该实现更加敏捷且对贡献者友好——因为它内部基于众所周知的基础类型/API(ASP.NET Core 服务 API 和 HTTP/2 客户端),并且它使用纯 C# 实现,代码对 C# 开发者来说更易于访问(无论是想了解其工作原理的用户,还是可能编写拉取请求的潜在贡献者)。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 核心原生库构建,因此所有不需要 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 也在使用它们。
- 提供 C# 项目代码生成构建集成的 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 核心迁移到 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 的扩展支持仅限于 Grpc.Core 作为这些客户端库一部分使用时提供。对于 Google Cloud 客户端库之外的其他用例,Grpc.Core 在弃用日期之后将不再获得官方支持,用户必须在弃用发生之前将其现有工作负载迁移到 grpc-dotnet。
我在哪里可以找到支持的功能列表?
我们 GitHub 上的文档包含支持功能的比较。
我有一个本文档未涵盖的重要 Grpc.Core 用例。