迁移到到.NET Core后各种服务指标变化对比

103 阅读6分钟

微软365(M365)是一套广泛的生产力服务,能够实现团队合作、沟通和相关体验。大部分代码库是用C#编写的。我想告诉你关于 "M365底层 "服务的.NET核心的旅程。Substrate是一套服务,你可以认为它是微软Exchange的后代。事实上,Exchange是微软第一个采用.NET并部署为64位的服务。

Substrate是一个成熟的、非常有规模的产品。我们有三个原因促使我们转移到.NET核心。第一个原因是我们非常需要性能和成本效益的提高。任何基于云的供应商都知道,每一个低效率都要付出真正的金钱。第二个原因是,我们知道.NET框架已经不再积极开发,我们想转移到一个现代框架,它正在开拓一条通往未来的道路。第三,也可能是更重要的是,它很酷、很亮、很新。

虽然我们有许多辅助服务的git仓库,但Substrate的核心包含在 "Substrate "git仓库中。这个仓库里有大约3400个产品代码的C#项目,另外3400个测试代码的项目和1000多个C++项目。我们的生产服务在200,000多台机器的混合体上运行100多个不同的进程和应用池,并且有1000多个贡献的开发者。

方法论

转换工作从一个团队开始,集中在一个单一的协议上,作为概念迁移的证明 - POP3协议。与其他协议相比,POP3协议的使用量较少,需要转换的依赖组件的网络也较小;因此,它很适合作为第一次迁移。即便如此,还是有大约140个程序集和NuGet包需要迁移到.NET核心。

鉴于一个.NET Core程序集只能使用其他.NET Core(或标准)程序集,我们需要确定迁移这些程序集的顺序。我们在日常构建的基础上建立了一个依赖性图表工具,它显示了给定协议的程序集依赖性(直接和间接),显示了这些程序集中哪些是与.NET核心兼容的(使用.NET可移植性分析器),并显示了将这些程序集迁移到.NET核心会如何影响到底层的其他进程/应用程序池。

虽然我们最初把许多常用程序集的目标定为.NET标准2.0,但我们最终放弃了.NET标准,选择了多目标,直到我们所有的项目都被迁移,这时我们将只生成.NET Core程序集。这使我们能够使用.NET Core中的新功能,而不是坚持使用.NET Framework和.NET Core之间的共同功能。

转换进展

在写这篇文章的时候,我们已经成功迁移了Substrate repo中的1061个程序集。这些转换使我们能够在.NET Core上运行以下服务:

  • POP3服务
  • IMAP4服务
  • Mapi-Http应用池
  • MSExchangeTransportLogSearch服务
  • MSExchangeTransportStreamingOptics服务
  • 正在进行中 - http.sys上的EAS
  • 我们的测试和验证系统

迁移到.NET核心的一个重大挑战是,我们引用了大量的NuGet包(包括MSFT内部和外部)。在某些情况下,当这些包中没有.NET标准2.0或.NET核心的产品时,必须找到这些包的所有者。这让我们看到了保持最新的软件包所有权映射的重要性。

流程迁移

应该指出的是,我们有许多新的.NET Core应用程序,但鉴于这些不是迁移,我们没有前后的数字可以比较。下面我们将深入探讨我们已经完成的迁移及其结果。

POP3

POP3是一个Windows服务,它实现了用于邮箱数据检索的POP3协议。下表显示了我们在这个过程中遇到的几个指标的改进:

Pop3 performance gains moving to .NET Core

值得注意的是,这些性能优势并不包括转移到更现代的.NET概念,如跨度和内存。一旦我们这样做,我们希望能进一步节省开支。

IMAP4

我们的IMAP4进程的迁移方式与POP3略有不同,所以很难得到一个好的.NET框架与.NET核心的比较,但最近我们刚刚将IMAP4从.NET 5提升到.NET 6,并注意到由于升级而提高的性能,如下表所示:

Imap4 performance gains moving from .Net 5 to .Net 6

使用.NET 6后,CPU和内存的使用率都降低了。虽然在IMAP4代码中还有一些其他变化,可能有助于提高性能,但很可能.NET 6才是主要的贡献者。

Mapi Http

MapiHttp是一个基于IIS的应用池,被迁移到一个基于Kestrel的应用程序。对于MapiHttp,我们测量了以下改进:

MapiHttp performance gains moving to .NET Core

CSO

CSO是一个.NET Core 6,基于Kestrel的gRPC服务,位于Exchange商店之上。它的目的是为数据中心内的其他节点提供一个快速访问协议(与RPC相反,RPC对于盒子外的通信来说是相当健谈的)。鉴于CSO最初是作为一个.NET Core应用程序创建的,我们不能显示与.NET框架版本的任何比较。然而,CSO的一个场景显示了显著的改进,即项目查询,我们从邮箱数据库中获取分页视图。我们将REST API(ASP.NET,NET框架RESTful服务)中现有的项目查询功能与我们基于kestrel的CSO,gRPC解决方案进行了比较。结果给我们留下了深刻的印象,包括以下几点:

CSO ItemQuery performance compared to REST

值得注意的是,这并不是一个苹果对苹果的比较。这是一个不同的服务,它使用gRPC,而且它是使用较新的结构并考虑到效率的情况下编写的。不过,使这项服务比其前身表现得更好的许多功能都可以归功于.NET核心和相关产品(gRPC、Kestrel等)。

未来发展

考虑到迁移到.NET核心所带来的令人印象深刻的性能优势,我们的北极星目标是将所有Substrate进程迁移到.NET核心,并将所有内部微服务迁移到使用gRPC进行通信。此外,我们的构建团队所实现的基础设施变化将使这个大规模的产品在.NET版本可用时保持在最前沿,以确保我们在最佳水平上运行,并为我们的客户提供最大的性能优势。