.NET9?AOT部署方案詳解
概念
AOT是Ahead-of-Time的縮寫,AOT是將C#程序提前編譯為機(jī)器代碼(通常為平臺(tái)特定的二進(jìn)制文件),在應(yīng)用程序啟動(dòng)之前完成編譯過(guò)程。
微軟官方文檔是這樣說(shuō)的
將應(yīng)用程序發(fā)布為本機(jī) AOT 會(huì)生成一個(gè)自包含的應(yīng)用程序,并且已提前 (AOT) 編譯為本機(jī)代碼。原生 AOT 應(yīng)用程序具有更快的啟動(dòng)時(shí)間和更小的內(nèi)存占用。這些應(yīng)用可以在未安裝 .NET 運(yùn)行時(shí)的計(jì)算機(jī)上運(yùn)行。 原生 AOT 的優(yōu)勢(shì)對(duì)于具有大量已部署實(shí)例的工作負(fù)載(例如云基礎(chǔ)設(shè)施和超大規(guī)模服務(wù))最為明顯。.NET 8 添加了對(duì)本機(jī) AOT 的 ASP.NET Core 支持。 本機(jī) AOT 部署模型使用預(yù)先編譯器在發(fā)布時(shí)將 IL 編譯為本機(jī)代碼。本機(jī) AOT 應(yīng)用程序在應(yīng)用程序運(yùn)行時(shí)不使用實(shí)時(shí) (JIT) 編譯器。本機(jī) AOT 應(yīng)用程序可以在不允許 JIT 的受限環(huán)境中運(yùn)行。本機(jī) AOT 應(yīng)用程序以特定的運(yùn)行時(shí)環(huán)境為目標(biāo),例如 Linux x64 或 Windows x64,就像發(fā)布自包含應(yīng)用程序一樣。
C# AOT部署和JIT部署兩種不同的編譯和部署方式對(duì)比
AOT(Ahead-of-Time)部署:
AOT是將C#程序提前編譯為機(jī)器代碼(通常為平臺(tái)特定的二進(jìn)制文件),在應(yīng)用程序啟動(dòng)之前完成編譯過(guò)程。
優(yōu)點(diǎn):
- 啟動(dòng)速度快:由于已經(jīng)提前編譯成機(jī)器代碼,應(yīng)用程序可以直接執(zhí)行,減少了啟動(dòng)時(shí)的編譯延遲。
- 內(nèi)存占用低:不需要在運(yùn)行時(shí)為JIT編譯分配額外內(nèi)存,避免了JIT編譯過(guò)程中可能的內(nèi)存開銷。
- 跨平臺(tái)支持:AOT編譯后,可以生成特定平臺(tái)的本地代碼,能夠更好地支持跨平臺(tái)部署。
- 安全性:由于所有的代碼已經(jīng)提前編譯為機(jī)器代碼,JIT編譯的潛在安全風(fēng)險(xiǎn)(如代碼注入等)較少。
- 性能穩(wěn)定:AOT編譯會(huì)優(yōu)化代碼,尤其適用于性能要求嚴(yán)格的場(chǎng)景,能夠提供更穩(wěn)定的執(zhí)行性能。
缺點(diǎn):
- 編譯時(shí)間長(zhǎng):AOT需要在部署前進(jìn)行編譯,可能導(dǎo)致部署的時(shí)間較長(zhǎng)。
- 平臺(tái)依賴:AOT編譯會(huì)生成特定平臺(tái)的機(jī)器碼,因此跨平臺(tái)部署需要針對(duì)每個(gè)平臺(tái)生成不同版本的代碼。
- 靈活性較低:JIT可以根據(jù)運(yùn)行時(shí)的環(huán)境和數(shù)據(jù)進(jìn)行動(dòng)態(tài)優(yōu)化,而AOT在編譯時(shí)就決定了優(yōu)化策略,缺乏運(yùn)行時(shí)調(diào)整的靈活性。
JIT(Just-in-Time)部署:
JIT是在應(yīng)用程序運(yùn)行時(shí)將中間語(yǔ)言(IL)編譯為機(jī)器代碼,編譯過(guò)程是動(dòng)態(tài)發(fā)生的。
優(yōu)點(diǎn):
- 快速開發(fā):JIT編譯能夠即時(shí)將中間語(yǔ)言編譯為本地代碼,因此可以更靈活地進(jìn)行開發(fā)和調(diào)試。
- 跨平臺(tái)支持:通過(guò)運(yùn)行時(shí)環(huán)境(如.NET Core或Mono),JIT可以支持多平臺(tái)的代碼編譯,而不需要為每個(gè)平臺(tái)單獨(dú)編譯。
- 運(yùn)行時(shí)優(yōu)化:JIT可以根據(jù)應(yīng)用程序的運(yùn)行環(huán)境和具體數(shù)據(jù)動(dòng)態(tài)生成優(yōu)化的機(jī)器代碼,可能會(huì)實(shí)現(xiàn)更高的性能,尤其是在具有不同負(fù)載的應(yīng)用場(chǎng)景下。
- 更高的靈活性:JIT可以在運(yùn)行時(shí)處理平臺(tái)和硬件特性,為應(yīng)用程序生成最合適的代碼。
缺點(diǎn):
- 啟動(dòng)時(shí)間慢:JIT編譯需要在運(yùn)行時(shí)將代碼編譯為機(jī)器代碼,因此啟動(dòng)速度較慢,特別是在初次運(yùn)行時(shí)。
- 額外內(nèi)存開銷:JIT編譯需要在內(nèi)存中保存編譯生成的機(jī)器代碼,這可能導(dǎo)致內(nèi)存占用較高。
- 性能波動(dòng):由于JIT編譯是在運(yùn)行時(shí)進(jìn)行的,可能導(dǎo)致執(zhí)行過(guò)程中存在性能波動(dòng),尤其是在復(fù)雜的代碼路徑上。
總結(jié):
- AOT部署適用于需要快速啟動(dòng)、內(nèi)存占用較低、性能要求穩(wěn)定的場(chǎng)景,例如嵌入式設(shè)備或資源受限的應(yīng)用。它的主要缺點(diǎn)是編譯時(shí)間較長(zhǎng)以及缺乏運(yùn)行時(shí)優(yōu)化的靈活性。
- JIT部署適用于需要較高靈活性、支持多平臺(tái)和快速開發(fā)的場(chǎng)景,它能動(dòng)態(tài)優(yōu)化性能,但啟動(dòng)時(shí)間較長(zhǎng),并可能帶來(lái)額外的內(nèi)存開銷。
選擇AOT還是JIT部署,需要根據(jù)具體的應(yīng)用場(chǎng)景、性能需求、開發(fā)周期和平臺(tái)要求來(lái)權(quán)衡。
實(shí)操
創(chuàng)建一個(gè)解決方案,創(chuàng)建兩個(gè)控制臺(tái)項(xiàng)目,一個(gè)啟用AOT,一個(gè)不啟用
未啟用AOT的csproj文件內(nèi)容
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> </Project>
啟用AOT的csproj文件內(nèi)容
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFramework>net9.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <PublishAot>true</PublishAot> <InvariantGlobalization>true</InvariantGlobalization> </PropertyGroup> </Project>
通過(guò)對(duì)比可以發(fā)現(xiàn)就這個(gè)配置
<PublishAot>true</PublishAot>
啟用AOT
參考官方文檔:
https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/?tabs=windows%2Cnet8
AOT部署一般要在csproj增加如下配置
<PublishAot>true</PublishAot> <IsAotCompatible>true</IsAotCompatible> <StripSymbols>false</StripSymbols> <PlatformTarget>x64</PlatformTarget>
<PublishAot>true</PublishAot>
此屬性在發(fā)布期間啟用本機(jī) AOT 編譯<IsAotCompatible>true</IsAotCompatible>
該屬性用于指示庫(kù)是否與本機(jī) AOT 兼容<StripSymbols>false</StripSymbols>
調(diào)試文件對(duì)于在調(diào)試器下運(yùn)行應(yīng)用程序或檢查故障轉(zhuǎn)儲(chǔ)是必需的。在類 Unix 平臺(tái)上,將該屬性設(shè)置為在本機(jī)二進(jìn)制文件中包含調(diào)試信息。包含調(diào)試信息會(huì)使本機(jī)二進(jìn)制文件更大<PlatformTarget>x64</PlatformTarget>
目標(biāo)平臺(tái)內(nèi)容是AnyCPU、x86、x64、ARM32、ARM64,一般選擇x64/AnyCPU即可,其它平臺(tái)看場(chǎng)景
發(fā)布到Win系統(tǒng)的AOT
發(fā)布命令參考:
https://learn.microsoft.com/zh-cn/dotnet/core/deploying/ready-to-run
https://learn.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish
1.直接使用VS進(jìn)行發(fā)布
2.使用dotnet命令
使用cmd進(jìn)入到在csproj文件夾目錄,執(zhí)行dotnet命令
dotnet publish -c Release -r win-x64 -p:PublishReadyToRun=true
發(fā)布到Liunx系統(tǒng)的AOT
如果直接在VS 2022上發(fā)布到Liunx的AOT部署會(huì)報(bào)下面錯(cuò)誤
Cross-OS native compilation is not supported.
1、在 os-linux-ubuntu-2204 上安裝 .NET SDK 或 .NET 運(yùn)行時(shí)
使用包管理器安裝
參考文檔:
添加存儲(chǔ)庫(kù)
sudo add-apt-repository ppa:dotnet/backports
安裝SDK
sudo apt-get update && \ sudo apt-get install -y dotnet-sdk-9.0
安裝運(yùn)行時(shí)
#ASP.NET Core 運(yùn)行時(shí) sudo apt-get update && \ sudo apt-get install -y aspnetcore-runtime-9.0
#.NET 運(yùn)行時(shí) sudo apt-get install -y dotnet-runtime-9.0
使用腳本安裝
參考文檔
https://learn.microsoft.com/zh-cn/dotnet/core/install/linux-scripted-manual#scripted-install
# 通過(guò) wget 下載腳本 wget https://dot.net/v1/dotnet-install.sh -O dotnet-install.sh
#可執(zhí)行文件運(yùn)行的權(quán)限 chmod +x ./dotnet-install.sh
此腳本默認(rèn)安裝最新的長(zhǎng)期支持 (LTS) SDK 版本,即 .NET 8。 若要安裝最新版本(可能不是 (LTS) 版本),請(qǐng)使用 --version latest 參數(shù)。
./dotnet-install.sh --version latest # 若要安裝 .NET 運(yùn)行時(shí)而非 SDK,請(qǐng)使用 --runtime 參數(shù)。 ./dotnet-install.sh --version latest --runtime aspnetcore # 可以通過(guò) --channel 參數(shù)更改特定主要版本來(lái)指示特定版本。 以下命令安裝 .NET 9.0 SDK。 ./dotnet-install.sh --channel 9.0
手動(dòng)安裝
參考文檔:http://www.dbjr.com.cn/aspnet/334718iq4.htm
下載SDK/runtime地址:https://dotnet.microsoft.com/zh-cn/download/dotnet/9.0
這里下載的是dotnet-sdk-9.0.102-linux-x64.tar.gz
# 創(chuàng)建文件夾 sudo mkdir -p /usr/dotnet/9.0.102 # 解壓文件 sudo tar xzf dotnet-sdk-9.0.102-linux-x64.tar.gz -C /usr/dotnet/9.0.102/ # 使用vim修改/etc/profile文件/或者使用SSH更改文件 sudo vim /etc/profile # 在/etc/profile文件下增加下面內(nèi)容 export DOTNET_HOME=/usr/dotnet/9.0.102 export PATH=${DOTNET_HOME}:$PATH # 重新加載系統(tǒng)級(jí)別的環(huán)境配置文件 source /etc/profile
2、檢查安裝.NET的版本
# 查看版本 dotnet --version # 檢查 SDK 版本 dotnet --list-sdks # 檢查運(yùn)行時(shí)版本 dotnet --list-runtimes
3、 安裝C++編譯工具
參考文檔:
http://www.dbjr.com.cn/aspnet/334726wux.htm
https://learn.microsoft.com/zh-cn/dotnet/core/deploying/native-aot/?tabs=linux-ubuntu%2Cnet9plus
sudo apt-get install clang zlib1g-dev
4、把解決方案代碼上傳到Linux系統(tǒng)某個(gè)文件夾上并轉(zhuǎn)到要發(fā)布的項(xiàng)目csproj文件所在目錄上
5、執(zhí)行dotnet命令發(fā)布
dotnet publish -c Release -r linux-x64 --self-contained /p:PublishAot=true
到此這篇關(guān)于.NET9 AOT部署方案詳解的文章就介紹到這了,更多相關(guān).NET9 AOT部署內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
WPF關(guān)鍵幀動(dòng)畫介紹與實(shí)現(xiàn)
這篇文章介紹了WPF關(guān)鍵幀動(dòng)畫與實(shí)現(xiàn)方式,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-01-01asp.net viewstate 回發(fā)機(jī)制
ASP.NET中,為了模擬Winform中的事件響應(yīng)機(jī)制,微軟的工程師真是煞費(fèi)苦心,發(fā)明了“回發(fā)”機(jī)制,使得編寫WEB頁(yè)面變得和Winform一樣簡(jiǎn)單。2010-03-03ASP.net中Core自定義View查找位置的實(shí)例代碼
在本篇文章里小編給大家分享的是關(guān)于ASP.net中Core自定義View查找位置的實(shí)例代碼,需要的朋友們可以學(xué)習(xí)下。2020-04-04ASP.NET連接 Access數(shù)據(jù)庫(kù)的幾種方法
這篇文章主要介紹了ASP.NET連接 Access數(shù)據(jù)庫(kù)的幾種方法,每種方法都非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友一起學(xué)習(xí)吧2016-08-08asp.net jQuery Ajax用戶登錄功能的實(shí)現(xiàn)
前幾天把jbox源碼修改成仿QQ空間模擬窗口后發(fā)現(xiàn)有很多人在關(guān)注。今天就貼一下我利用該模擬窗口實(shí)現(xiàn)的用戶登錄功能的代碼。2009-11-11使用ajax局部刷新gridview進(jìn)行數(shù)據(jù)綁定示例
很多用戶都有這樣需求,比如:點(diǎn)擊按鈕,刷新 GridView 中的數(shù)據(jù),而不是這個(gè)頁(yè)面刷新。使用簡(jiǎn)單的 XMLHttpRequest就可以直接實(shí)現(xiàn)2014-02-02asp.net簡(jiǎn)單實(shí)現(xiàn)單點(diǎn)登錄(SSO)的方法
這篇文章主要介紹了asp.net簡(jiǎn)單實(shí)現(xiàn)單點(diǎn)登錄(SSO)的方法,結(jié)合簡(jiǎn)單實(shí)例形式較為詳細(xì)的分析了單點(diǎn)登錄的原理與asp.net的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-12-12ASP.NET服務(wù)器端控件RadioButtonList,DropDownList,CheckBoxList的取值、賦值
這三個(gè)控件都有一個(gè)Items集合,可以用 RepeatLayout 和 RepeatDirection 屬性來(lái)控制列表的呈現(xiàn)形式2013-10-10