进击的.NET 在云原生时代的蜕变

你必定看过这篇文章 《进击的 Java ,云原生时代的蜕变》,  本篇文章的灵感来自于这篇文章。北京时间9.24 就将正式发布.NET Core 3.0, 因此写下这篇文章让你们全面认识.NET Core。html

.NET 生态系统是一个不断变化的生态圈,我相信它正在朝着一个伟大的方向发展。正好 最近 InfoQ 上发布了一篇文章《.NET 生态系统概览》,有了开源和跨平台这两个关键优先事项,咱们就能够放心了。 下面咱们来参考文章《进击的 Java ,云原生时代的蜕变》对云原生对应用运行时的不一样需求,说明一个.NET Core 3.0 在云原生时代所完成的蜕变:java

  • 体积更小:对于微服务分布式架构而言,更小的体积意味着更少的下载带宽,更快的分发下载速度,.NET Core 的镜像体积都很小,alpine的镜像更小,带上应用程序一般80M。
  • 启动速度更快:对于传统单体应用,启动速度与运行效率相比不是一个关键的指标。缘由是,这些应用重启和发布频率相对较低。然而对于须要快速迭代、水平扩展的微服务应用而言,更快的的启动速度就意味着更高的交付效率,和更加快速的回滚。尤为当你须要发布一个有数百个副本的应用时,缓慢的启动速度就是时间杀手。对于Serverless 应用而言,端到端的冷启动速度则更为关键,即便底层容器技术能够实现百毫秒资源就绪,若是应用没法在 500ms 内完成启动,用户就会感知到访问延迟。这里我拿AWS Lambda来举例,由于各大云厂商都是以AWS是模仿的目标,AWS Lambda中可用的全部语言都是高级的,而不是像Assembler,C / C ++或Objective C那样。从脚本语言到JavaScript和Python,再到像Java和C#到Go这样被编译为二进制文件的托管运行时的语言,全部语言都是他们有本身的长处。在基准测试中,最重要的.NET Core是 冠军,具体参看https://react-etc.net/entry/aws-lambda-benchmarks-node-js-python-java-c-go-dotnet-core
  • 占用资源更少:运行时更低的资源占用,意味着更高的部署密度和更低的计算成本。.NET Core的 CLR启动速度很是快,下降启动时资源消耗,能够减小资源争抢,更好保障其余应用 SLA。
  • 支持水平扩展:.NET Core 3.0默认更好的支持Docker资源限制,官方团队也在努力让.NET Core成为真正的容器运行时,使其在低内存环境中具备容器感知功能并高效运行。 具体能够参看文章《从CLR GC到CoreCLR GC看.NET Core对云原生的支持》,随着内存成本的降低和虚拟化的流行,大内存配比已经成为趋势。因此咱们通常是采用水平扩展的方式,同时部署多个应用副本,在一个计算节点中可能运行一个应用的多个副原本提高资源利用率。

.NET Core 3.0 新增功能 大部分的功能特性已经公开,能够经过网页:https://docs.microsoft.com/zh-cn/dotnet/core/whats-new/dotnet-core-3-0,其中有几个特性是很是期待应用到生产的,不少人都在等待着明天的正式发布。node

默承认执行文件

.NET Core 如今默认生成依赖于框架的可执行文件,这个行为是和.NET Framework保持一致了。 对于使用全局安装的 .NET Core 版本的应用程序而言,这是一种新行为。 之前,仅独立部署会生成可执行文件。python

dotnet builddotnet publish 期间,将建立一个与你使用的 SDK 的环境和平台相匹配的可执行文件。 和其余本机可执行文件同样,可使用这些可执行文件执行相同操做,例如:react

  • 能够双击可执行文件。
  • 能够直接从命令提示符启用应用程序,如 Windows 上的 myapp.exe,以及 Linux 和 macOS 上的 ./myapp

单文件可执行文件

dotnet publish 命令支持将应用打包为特定于平台的单文件可执行文件。 该可执行文件是自解压缩文件,包含运行应用所需的全部依赖项(包括本机依赖项)。 首次运行应用时,应用程序将根据应用名称和生成标识符自解压缩到一个目录中。 再次运行应用程序时,启动速度将变快。 除非使用了新版本,不然应用程序无需再次进行自解压缩。git

若要发布单文件可执行文件,请使用 dotnet publish 命令在项目或命令行中设置 PublishSingleFilegithub

<PropertyGroup>
   <RuntimeIdentifier>win10-x64</RuntimeIdentifier>
   <PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>docker

或者 编程

dotnet publish -r win10-x64 /p:PublishSingleFile=true缓存

这个单文件是你们一直期待的go 特性,.NET Core 3.0正式有了,更详细的信息参看 https://github.com/dotnet/designs/blob/master/accepted/single-file/design.md

程序集连接

.NET core 3.0 SDK 随附了一种工具,能够经过分析 IL 并剪裁未使用的程序集来减少应用的大小。

自包含应用包括运行代码所需的全部内容,而无需在主计算机上安装 .NET。 可是,不少时候应用只须要一小部分框架便可运行,而且能够删除其余未使用的库。

.NET Core 如今包含一个设置,将使用 IL 连接器工具扫描应用的 IL。 此工具将检测哪些代码是必需的,而后剪裁未使用的库。 此工具能够显著减小某些应用的部署大小。

要启用此工具,请使用项目中的 <PublishTrimmed> 设置并发布自包含应用:

<PropertyGroup>
   <PublishTrimmed>true</PublishTrimmed>
</PropertyGroup>

或者

dotnet publish -r <rid> -c Release

例如,包含的基本“hello world”新控制台项目模板在发布时命中大小约为 70 MB。 经过使用 <PublishTrimmed>,其大小将减小到约 30 MB,这个特性能够用于进一步的减少应用程序的大小。请务必考虑到使用反射或相关动态功能的应用程序或框架(包括 ASP.NET Core 和 WPF)一般会在剪裁时损坏。

分层编译

.NET Core 3.0 中默认启用了分层编译 (TC)。 此功能使运行时可以更适应地使用实时 (JIT) 编译器来得到更好的性能,这也是一个能够加速应用启动的选项。

TC 的主要优点是使(从新)实时编译方法可以要么牺牲代码质量以更快地生成代码,要么以较慢的速度生成更高质量的代码。 这有助于提升应用程序在从启动到稳定状态的各个执行阶段的性能。 这与非 TC 方法彻底不一样,其中每种方法均以单一方式进行编译(与高质量层相同),这种方法偏向于稳定状态而不是启动性能。

若要启用快速 JIT(第 0 层实时编译的代码),请在项目文件中使用此设置:

<PropertyGroup>
   <TieredCompilationQuickJit>true</TieredCompilationQuickJit>
</PropertyGroup>

ReadyToRun 映像

能够经过将应用程序集编译为 ReadyToRun (R2R) 格式来改进.NET Core 应用程序的启动时间。 R2R 是一种预先 (AOT) 编译形式,这也是一项加速应用启动时间的选项。

R2R 二进制文件经过减小应用程序加载时实时 (JIT) 编译器须要执行的工做量来改进启动性能。 二进制文件包含与 JIT 将生成的内容相似的本机代码。 可是,R2R 二进制文件更大,由于它们包含中间语言 (IL) 代码(某些状况下仍须要此代码)和相同代码的本机版本。仅当发布面向特定运行时环境 (RID)(如 Linux x64 或 Windows x64)的自包含应用时 R2R 才可用。

主要版本前滚

.NET Core 3.0 引入了一项选择加入功能,该功能容许应用前滚到 .NET Core 最新的主要版本。 此外,还添加了一项新设置来控制如何将前滚应用于应用。 这能够经过如下方式配置:

  • 项目文件属性:RollForward
  • 运行时配置文件属性:rollForward
  • 环境变量:DOTNET_ROLL_FORWARD
  • 命令行参数:--roll-forward

必须指定如下值之一。 若是省略该设置,则默认值为“Minor” 。

  • LatestPatch
    前滚到最高补丁版本。 这会禁用次要版本前滚。
  • Minor
    若是缺乏所请求的次要版本,则前滚到最低的较高次要版本。 若是存在所请求的次要版本,则使用 LatestPatch 策略。
  • Major
    若是缺乏所请求的主要版本,则前滚到最低的较高主要版本和最低的次要版本。 若是存在所请求的主要版本,则使用 Minor 策略。
  • LatestMinor
    即便存在所请求的次要版本,仍前滚到最高次要版本。 适用于组件托管方案。
  • LatestMajor
    即便存在所请求的主要版本,仍前滚到最高主要版本和最高次要版本。 适用于组件托管方案。
  • Disable
    不前滚。 仅绑定到指定的版本。 建议不要将此策略用于通常用途,由于它会禁用前滚到最新补丁的功能。 该值仅建议用于测试。

Docker 和 cgroup 内存限制

从预览版 3 开始,在 Linux 上使用 Docker 运行 .NET Core 3.0 时,能够更好地处理 cgroup 内存限制。 运行具备内存限制的 Docker 容器(例如使用 docker run -m)会更改 .NET Core 的行为方式。

  • 默认垃圾回收器 (GC) 堆大小:最大为 20 MB 或容器内存限制的 75%。
  • 能够将显式大小设置为绝对数或 cgroup 限制的百分比。
  • 每一个 GC 堆的最小保留段大小为 16 MB。 此大小可减小在计算机上建立的堆数量。

垃圾回收堆大小减少

垃圾回收器的默认堆大小已减少,以使 .NET Core 使用更少的内存。 此更改更符合具备现代处理器缓存大小的第 0 代分配预算。

垃圾回收大型页面支持

大型页面(也称为 Linux 上的巨型页面)是一项功能,其中操做系统可以创建大于本机页面大小(一般为 4K)的内存区域,以提升请求这些大型页面的应用程序的性能。

如今可使用 GCLargePages 设置将垃圾回收器配置为一项选择加入功能,以选择在 Windows 上分配大型页面。


.NET 技术在云原生时代也在不停地进化。.NET Core 做为.NET 生态的很是重要的一员,在对现有 .NET 应用保持高度兼容的同时,对启动速度和内存占用作了细致的优化,比较适于微服务架构配合使用, 在以kubernetes 为表明的云原生应用开发平台上发生蜕变。

在云原生时代,咱们要可以在横向的应用开发生命周期中,将开发、交付、运维过程进行有效的分割和重组,提高研发协同效率;而且要能在整个纵向软件技术栈中,在编程模型、应用运行时和基础设施等多层面进行系统优化,实现 radical simplification,提高系统效率。

相关文章
相关标签/搜索