Microsoft Teams 的 .NET Core 之旅
Microsoft Teams “MiddleTier” 是支持 Microsoft Teams 中各种方案的内部服务。它由 700 多个 API 组成,是由 Microsoft 的 10 多个团队维护的最大服务之一。在过去两年中,此服务下的 50 多个项目(库、测试、应用程序)已转换到 .NET Standard 2.0 和 .NET Core 3.1,具有等效的功能和性能(或更佳),目前在生产中已几乎完全在 .NET Core 3.1 上运行,并且希望下一步移动到 .NET 6。在此迁移之前,该服务使用 ASP.NET Core 2.2 MVC 管道在 .NET Framework 4.6.2 上运行。它在 Azure Service Fabric上运行,并且部署在 35 个 Azure 数据中心。
此迁移的范围很大,因为就它每天为数百名使用它的开发人员提供的功能而言,MiddleTier 是一项超大型服务。
迁移动机
团队乐于迁移到 .NET Core 3.1 的原因如下:
- 性能和成本效益提升
- .NET Framework 4.6.2 可能即将过期
- 跨平台支持
- 迁移到新式框架以获得更好的开发人员体验
迁移到 .NET Core 3.1 后的好处
迁移到 .NET Core 3.1 后,团队已注意到以下改进:
- 25% 的 CPU 改进
- 降低了大约 25% 的基础结构成本
- 改进的线程池使用率
- 降低了向年度 .NET 版本迁移的技术债务和工作量
下图显示了 .NET Framework 与 .NET Core 之间的比较。将来在 .NET 6 上,我们应会看到进一步的改进。
方法
整体迁移分为三个阶段进行:
他们还选择将应用程序设置为多目标,即同时面向 .NET Framework 和 .NET Core,以便可以同时拥有两个可用的二进制文件,并且可以继续缓慢推出 .NET Core。
学习
OData 和其他 REST API 无法共享路由前缀
他们的服务包含几个 OData 终结点以及许多 REST 终结点。这两类终结点共享相同的路由前缀。此设置过去在 .NET Framework 中可正常工作,但由于路由更改,已停止在 .NET Core 中正常工作。他们必须将 OData API 移动到其他路由前缀才能解决此问题。
OData 客户端库的性能问题
与.NET Framework相比,使用 OData 客户端调用下游 OData API 的 HttpWebRequest 模式会导致更高的延迟。这是由于框架不缓存连接的 .NET Core 中的回归所导致的。此问题已在较新版本的 .NET 中得到解决。
Azure 服务总线 SDK 问题
作为此迁移的一部分,Azure 服务总线 SDK 必须进行升级,因为旧版本与 .NET Standard 不兼容。最新版本的 Azure 服务总线 SDK 以 JSON 格式发送请求有效负载,而较旧的 SDK 则以 XML 格式发送有效负载。要继续使用 XML 有效负载,他们必须使用 DataContractSerializer。
适用于多目标的 Service Fabric 项目中的问题
Service Fabric 项目(sfproj)本身不支持多目标。他们必须在生成管道中执行解决方法,以便为两个目标框架生成 Service Fabric 包。
关于较旧版本的 MimeKit NuGet 的问题
旧版本的 MimeKit 可能存在与双字节字符有关的问题,因此在此方案中建议进行特定于语言的验证。他们在向位于亚洲地区的部署推出时发现了类似的问题。
经典 ASP.NET 奇妙之处
- 必须移除在 .NET Core 中标记为内部的某些 .NET Framework 类的用法。
- 如《面向版本 3.0 和 3.1 的 ASP.NET Core 重大更改》一文所述,已从操作名称中删除 MVC 异步后缀。如果任何代码路径依赖于操作名称,则可能导致行为发生更改。
- 默认情况下,从 .NET Core 3.0 开始,已在所有服务器上禁用同步 IO 操作,如 dotnet/aspnetcore#7644 GitHub 问题中所述。
- 将 StreamContent 作为 HTTP 请求内容发送时,Content.Headers 中未设置 Content-Length 标头。这可能会导致下游调用出错。
- .NET framework 为字符串生成稳定的哈希代码,但 .NET Core 则不会生成。
- System.ComponentModel.DataAnnotations 命名空间中的必需属性与在 .NET Core 中的行为不同。在 .NET Framework 上,此属性不会对非 null 字段执行任何模型验证,但在 .NET Core 上则会执行此操作。
未来
每个新版本的 .NET 都附带了重大的生产力和性能改进,可继续帮助实现我们构建可复原、可缩放、高性能和安全服务的目标。团队下一步将通过升级到 .NET 6 来继续利用 .NET 中所做的改进。
准备好开始使用了吗?
分步教程将帮助你在计算机上运行 ASP.NET。