進擊的.NET 在雲原生時代的蛻變

来源:https://www.cnblogs.com/shanyou/archive/2019/09/22/11566850.html

你一定看過這篇文章 《進擊的 Java ,雲原生時代的蛻變》, 本篇文章的靈感來自於這篇文章。北京時間9.24 就將正式發佈.NET Core 3.0, 所以寫下這篇文章讓大家全面認識.NET Core。.NET 生態系統是一個不斷變化的生態圈,我相信它正在朝著一個偉大的方向發展。正好 最近 Inf... ...


你一定看過這篇文章 《進擊的 Java ,雲原生時代的蛻變》,  本篇文章的靈感來自於這篇文章。北京時間9.24 就將正式發佈.NET Core 3.0, 所以寫下這篇文章讓大家全面認識.NET Core。

.NET 生態系統是一個不斷變化的生態圈,我相信它正在朝著一個偉大的方向發展。正好 最近 InfoQ 上發佈了一篇文章《.NET 生態系統概覽》,有了開源和跨平臺這兩個關鍵優先事項,我們就可以放心了。 下麵我們來參考文章《進擊的 Java ,雲原生時代的蛻變》對雲原生對應用運行時的不同需求,說明一個.NET Core 3.0 在雲原生時代所完成的蛻變:

  • 體積更小:對於微服務分散式架構而言,更小的體積意味著更少的下載帶寬,更快的分發下載速度,.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,其中有幾個特性是非常期待應用到生產的,很多人都在等待著明天的正式發佈。

預設可執行文件

.NET Core 現在預設生成依賴於框架的可執行文件,這個行為是和.NET Framework保持一致了。 對於使用全局安裝的 .NET Core 版本的應用程式而言,這是一種新行為。 以前,僅獨立部署會生成可執行文件。

dotnet builddotnet publish 期間,將創建一個與你使用的 SDK 的環境和平臺相匹配的可執行文件。 和其他本機可執行文件一樣,可以使用這些可執行文件執行相同操作,例如:

  • 可以雙擊可執行文件。
  • 可以直接從命令提示符啟用應用程式,如 Windows 上的 myapp.exe,以及 Linux 和 macOS 上的 ./myapp

單文件可執行文件

dotnet publish 命令支持將應用打包為特定於平臺的單文件可執行文件。 該可執行文件是自解壓縮文件,包含運行應用所需的所有依賴項(包括本機依賴項)。 首次運行應用時,應用程式將根據應用名稱和生成標識符自解壓縮到一個目錄中。 再次運行應用程式時,啟動速度將變快。 除非使用了新版本,否則應用程式無需再次進行自解壓縮。

若要發佈單文件可執行文件,請使用 dotnet publish 命令在項目或命令行中設置 PublishSingleFile

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

或者

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,提升系統效率。


您的分享是我們最大的動力!

更多相關文章
  • 1、HttpClient遠程介面調用 1)用戶註冊 註冊按鈕 提交表單時,要 表單 js提交表單 2)載入外部資源文件 app.properties 編輯 RestApiServerInfo.java 3)HTTPClient工具遠程調用介面 導入依賴 發送post請求 工具類 遠程介面返回 封裝對 ...
  • 緩存的實現 我們不是做第三方比如Redis等的緩存實現,而是根據實際情況,基於C#上做一些環境變數的保存,方便項目使用。 1、系統全局變數 很多時候,在系統運行開始,需要對系統的運行參數進行保存,以便供全局使用。 代碼如下: 這裡使用一個靜態變數的Dictionary來進行保存,所有項目均可以直接獲 ...
  • 就像是.NET Framework WebApi與.NET Core WebApi一樣,.NET Framework MVC與.NET Core MVC的區別,也是框架的之間的區別。本系列先首先從.NET Framework MVC介紹,後面再去介紹.NET Core MVC 狹義MVC: MVC是 ...
  • 表達式樹練習實踐:C 值類型、引用類型、泛型、集合、調用函數 [TOC] 一,定義變數 C 表達式樹中,定義一個變數,使用 。 創建變數結點的方法有兩種, 兩種方式都是生成 類型 和 都具有兩個重載。他們創建一個 ParameterExpression節點,該節點可用於標識表達式樹中的參數或變數。 ...
  • 最近有個需求就是網頁表格裡面的數據導出到excel 於是從各位前輩的博客園搜了搜demo 大部分非為兩類 都是用的插件NPOI和Eppluse ,因此在這裡就介紹Eppluse 用法,還有就是在博客的時候 好多有留言說想看從資料庫裡面的數據進行導入 而不是寫死的,所以我就以我的案例給大家分享下用法( ...
  • 簡單創建.NET Core WebApi:https://www.cnblogs.com/yanbigfeg/p/9197375.html 登陸驗證四種方式:https://www.cnblogs.com/zuowj/p/5123943.html 解決跨域的8種方法:https://blog.csd ...
  • 非標設備多相機流水線模式緩存圖片(C/S客戶端,c 開發語言) ​ 本文所說流水線方式下存儲圖像是在軟體測量周期慢於圖片周期前提下講解的,如果軟體一直在等待圖片數據,邏輯就沒有那麼複雜。 1、非標設備項目,常規模式測量流程 常規模式下,相機採集圖像信號由上位機控制(無論軟觸發、硬觸發)。每個周期內的 ...
  • 參考文檔:Dapper one to many Table C Code pulic List GetPersons(){ var sql = @"SELECT 1 AS Id, 'Daniel Dennett' AS Name, 1942 AS Born, 1 AS CountryId, 'Uni ...
一周排行
  • 該方式是直接對屏幕進行截圖操作UserControl chartContainPanel = new UserControl();Graphics graph = chartContainPanel.CreateGraphics();Size s = chartContainPanel.Size;B... ...
  • dotnetcore3.1 WPF 中使用依賴註入 Intro 在 ASP.NET Core 中預設就已經集成了依賴註入,最近把 "DbTool" 遷移到了 WPF dotnetcore 3.1, 在 WPF 中我們也希望能夠使用依賴註入,下麵來介紹一下如何在 WPF dotnetcore3.1 中 ...
  • 原來的C 程式都有Main的,現在用vs新建一個Wpf項目,啟動似乎變成App.xmal,前期項目中為了獲取啟動參數,很是折騰了一番: 1.先是修改App.xaml,添加StartUp事件 2.然後編輯Application_Startup,判斷e.Args數組 總感覺跟又臭又長的裹腳布一樣,不爽。 ...
  • 冒泡排序原理:(升序)通過當前位置數和後一個位置數進行比較 如果當前數比後一個數大 則交換位置, 完成後 比較基數的位置變成下一個數。直到數組末尾,當程式運行完第一遍 最大的數已經排序到最後一個位置了。次數可以減少迴圈數不用管最後一個數 降序排序同理 不過是把比較方式變成判斷當前數是否小於下一個數 ...
  • 一、前言 這方面的資料很多,重覆的寫沒必要,但是最近一直在學習身份驗證和授權相關東東,為了成體系還是寫一篇,主要是從概念上理解identity系統。 參考:https://www.cnblogs.com/r01cn/p/5179506.html 二、概述 幾乎所有系統都包含用戶、角色、許可權、登錄、註 ...
  • 首先我們使用最簡單的模板案例,裡面有一個Counter計數器,你可以在創建模板中找到。 首先需要設置運行調試方式為IIS Express。這意味著,MAC可能不能使用調試。 然後開啟運行而不調試(Ctrl+F5) 按Shift + Alt + D,會出現一個新的頁面。 如果你想用Chrome調試,復 ...
  • 實體映射時,遇到複雜類型,可選擇下述方法處理: NotMapped,跳過映射 在複雜類型上聲明 [Owned],但僅限該複雜類型是全部由簡單值類型組成的 自定義序列化方法 示例: IPInfo使用了owned,對IPEndPoint使用自定義序列化,對VersionInfo使用JSON序列化 @@@... ...
  • .NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect 繼上一篇 ".net core 3 web api jwt 一直 401" 為添加 所述的坑後, 本次為添加 ,又踩坑了。 自從 .NET Core 2.2 之後,CORS跨域配置代碼發 ...
  • 在前一章已經學習過WPF動畫的第一條規則——每個動畫依賴於一個依賴項屬性。然而,還有另一個限制。為了實現屬性的動態化(換句話說,使用基於時間的方式改變屬性的值),需要有支持相應數據類型的動畫類。例如,Button.Width屬性使用雙精度數據類型。為實現屬性的動態化,需要使用DoubleAnimat ...
  • WPF dotnet core 3.1 基於 `Microsoft.Extensions.Localization` 實現基本的多語言支持 ...
x