前言 .NET在跨平臺後對於應用的部署而言,不在像.NET Framework的時候那麼單一化了,一個.NET Core應用的部署工作就可以涉及到很多知識點。 就對於windows而言,我們可以選擇使用IIS和Kestrel作為我們的Web伺服器。既可以把網站的部署用“進程內托管”方式插入IIS管道 ...
前言
.NET在跨平臺後對於應用的部署而言,不在像.NET Framework的時候那麼單一化了,一個.NET Core應用的部署工作就可以涉及到很多知識點。
就對於windows而言,我們可以選擇使用IIS和Kestrel作為我們的Web伺服器。既可以把網站的部署用“進程內托管”方式插入IIS管道中運行,以獲得更好的性能、更好的操控性。又可以用“進程外托管”方式將IIS作為反向代理伺服器將請求轉發給Kestrel伺服器進行處理,以獲得更多的配置項和安全性。
對於Linux而言,不光需要具備基本的系統知識和操作命令,還需要瞭解掌握虛擬機的安裝和使用。另外,還需要為部署的ASP.NET Core應用創建守護進程,以免系統在出現意外情況後,可以保證ASP.NET Core應用的正常運行。
不同的部署方式、不同的操作系統、不同的守護進程、不同的負載均衡伺服器等,在安裝、配置、使用上都有不同點。所以對於.NET的部署必須要有一個基本的瞭解和認識,並且需要對不同環境的部署具備一定的實際操作能力,我為此進行了大量的學習和總結,並撰寫了一些列有關ASP.NET Core部署的文章。
- 《ASP.NET Core部署手冊:部署基礎知識》
- 《ASP.NET Core部署手冊:Hyper-V虛擬機》
- 《ASP.NET Core部署手冊:Windows篇》
- 《ASP.NET Core部署手冊:註意事項和問題排查》
- 《ASP.NET Core部署手冊:Linux篇》
本系列文章主要的目的是作為常規部署的操作性指南,所以無法對每個細節點逐一進行介紹,如果想要深入細節,讀者可參考微軟文檔等資料進行綜合性學習。
1.部署模式
.NET Core應用程式在發佈的過程中會有兩種部署模式進行選擇,分別為“框架依賴”和“獨立”。
如果採用“獨立”模式進行發佈,那麼發佈生成的文件不僅包含項目程式集及其依賴的程式集,還會包含.NET運行時相關的文件,促使以該模式發佈的文件可以部署在沒有安裝.NET運行時的伺服器。
如果採用“框架依賴”的模式進行發佈,那麼發佈生成的文件只會包含項目中程式集及其依賴的程式集,以該模式部署的時候必須確保目標伺服器上安裝了.NET運行時。
在我看來“獨立”和“框架依賴”沒有好壞之分,它們各有千秋,我們需要結合實際的應用場景進行選擇,下麵對兩種模式做一個簡短的分析:
“框架依賴”:發佈後文件體積相對較小,並且項目框架所依賴的運行時在安裝後可以供給其他應用程式進行復用。最主要的是它可以生成用於所有操作系統平臺的“可執行文件”,所以在部署上具有跨平臺性,適用於一套應用部署在多個不同的操作系統。相比“獨立”模式而言,不足的就是必須單獨在目標伺服器上安裝.NET運行時。
“獨立”:相比“框架依賴”而言由於自身包含了.NET運行時,所以在文件體積上大很多,但是基於這一特點,促使在部署的時候更加方便和穩定(排查相容性問題)。由於生成的“可執行文件”是專屬於某個操作系統平臺的,所以如果要換其他的操作系統部署則必須重新編譯發佈。
PS:本系其他文章涉及到的部署方式都是所採用“框架依賴”的模式。
2.生成可執行文件
由於.NET Core是跨平臺的應用,所以對於在不同的操作系統和CPU體繫結構上運行都會存在一些差異性,因此.NET Core應用在發佈後會生成“可執行文件”,該文件主要用於處理不同平臺上運行時的差異性,該文件在發佈後主要在發佈目錄的“runtimes”文件夾中。
對於“框架依賴”模式而言它在選擇“目標運行時”時可以選擇.NET支持的所有操作系統平臺,也就是選擇“可移植”選項,因此具備各個平臺的“可執行文件”。而對於“獨立”模式而言,則必鬚根據部署伺服器的系統情況選擇一個具體的“目標運行時”,因此只具備一個平臺的“可執行文件”。
4.跨平臺可運行程式集
.NET應用在經過生成發佈的操作後,生成的程式集都是可以跨平臺的,而對於啟動項目的DLL程式集是直接可以通過dotnet命令,在包含了.NET運行時的任何操作系統運行。該dll文件通常與解決方案中啟動名稱相同(在分層的解決方案中,啟動項目通常為UI層),通常在Linux系統中都是以這種方式來運行項目。
5.為什麼“配置”選擇Debug或Release都會又pdb文件?
通常在預設的情況下,在發佈的時候不管“配置”選項選擇的Debug或Release,在最後發佈的文件夾中,對於每個項目都會生成一個pdb文件。這是因為“配置”選項本身和生成pdb文件是無關的,兩者都是單獨的設置。發佈時的“配置”選項的作用主要是用於優化生成後的程式集代碼,如果選擇“Release”,則編譯器會對代碼進行優化,將部署的程式集實現更小、更快、更高效的運行,這也是為什麼在進行“項目部署工作”的時候需要選擇“Release”,反之如果選擇Debug,那麼生成的程式集將更有利於我們進行程式調式。
對於pdb文件而言,它本身記錄了代碼中的斷點以及調式信息,專門用於我們調式程式,官方稱之為“調試符號文件”。由於pdb文件的生成會增加“發佈文件”的體積,所以通常情況下部署在生產環境中,pdb文件不是必須的,除非你想要遠程調式代碼。
如果部署項目時不需要pdb文件,推薦3種處理方式:
- 在使用“Release配置”發佈項目後,在發佈文件夾中人為手動刪除掉pdb文件即可;
- 在VS中打開項目的屬性設置,然後在左側點擊“生成”進入對於的設置頁面,找到“調式符合”區域在Release對於的下拉列表中選擇“未發出任何符合”,以VS2022為例如圖:
- 在VS中雙擊項目進入項目文件配置界面,在文件中新增“DebugType”節點,如圖:
6.Kestrel簡介
微軟為我們提供Web伺服器除了IIS以外的又一個選擇——Kestrel,該Web伺服器會內置到我們ASP.NET Core的項目模板中,換種直接的說法就是,我們的ASP.NET Core應用自帶了Web伺服器。Kestrel本身可以作為面向互聯網的Web伺服器,直接處理客戶端傳入的HTTP請求。
在Kestrel中,用於托管應用程式的進程是dotnet.exe,而非以往在IIS中的w3wp.exe了。當我們使用.NET CLI命令直接運行應用程式或直接打開exe文件時,此時應用程式就已經將Kestrel作為Web伺服器。
儘管Kestrel讓我們的部署運行更加方便,並且跨平臺、功能豐富、性能強大,且已經足以作為一個獨立Web伺服器使用了,但是在實際的工作項目中,我們通常不會讓Kestrel作為最終的Web伺服器直接處理終端用戶的請求。
因為Kestrel中很多操作都需要編寫代碼來完成,比如配置功能變數名稱證書、記錄請求日誌、URL重寫等,而這些操作在Nginx、IIS等伺服器中,都不需要我們編寫代碼,我們只需要修改配置文件即可完成這些任務,所以Kestrel對運維工作不太友好。
並且對於比較複雜的項目而言,為了提高系統的可用性,我們通常會加入代理伺服器,由代理服務將請求轉發給Kestrel,並實現負載均衡,將同樣的網站部署到多台Web伺服器上,由負載均衡伺服器決定把用戶請求轉發給哪台伺服器。
7.進程內托管和進程外托管
ASP.NET Core 應用在Web伺服器上進行部署托管,其中劃分為了兩種托管模型,分別為即進程內托管(InProcess)和進程外托管(OutOfProcess)。
7.1.進程內
對於直接將ASP.NET Core 應用部署運行在IIS工作進程(w3wp.exe)或IIS Express進程(iisexpress.exe)中的方式稱為進程內托管(InProcess)。 進程內托管的方式相較進程外托管提供更優的性能,因為請求並不通過環回適配器進行代理,環回適配器是一個網路介面,用於將傳出的網路流量返回給同一電腦。
下圖說明瞭 IIS、ASP.NET Core 模塊和進程內托管的應用之間的關係:
7.2.進程外
對於進程外托管(OutOfProcess)的部署而言,ASP.NET Core 應用不會直接部署運行在IIS工作進程中。通常會採用兩種方式,第一種是直接使用Kestrel作為Web伺服器面向外部處理HTTP請求,第二種則是通過一個代理伺服器(IIS、Nginx)進行請求轉發,在將請求轉發到Kestrel伺服器進行處理。
由於運行 ASP.NET Core 的進程與 IIS 工作進程分開,因此 ASP.NET Core Module模塊會負責管理ASP.NET Core應用的進程,其中包含Kestrel和應用程式。該模塊在第一個請求到達時會自動啟動 ASP.NET Core 應用的進程,併在應用關閉或崩潰時重新啟動該應用。
7.3.配置
下麵只針對IIS中如何配置這兩種托管模型進行介紹,因為對於其他的Web服務而言都屬於的是進程外托管這一種方式了,就談不上配置了。
將ASP.NET Core應用部署到IIS上預設採用的是進程內的托管方式,如果想要顯示的設置為托管方式,首先需要打開項目文件csproj,然後在其中加入<AspNetCoreHostingModel>標簽,標簽的值可設為:
- OutOfProcess(進程外)
- InProcess(進程內)
註意:如果你不使用IIS作為Web伺服器,而是直接使用Kestrel或代理伺服器,那麼無論標簽指定的值是InProcess或OutOfProcess,其運行方式都始終按照進程外托管(OutOfProcess)。
結語
在.NET開源跨平臺後,應用程式發佈這項工作不在比以往.NET Framework時代那麼簡單了,個人覺得對於應用程式發佈相關的知識必須系統的學習下,並且掌握或嘗試各主流操作系統下的部署技巧,這顯得尤為重要。雖然所涉及的知識面廣,但可以先進行粗略的全盤瞭解,然後在根據所處的工作實際情況,對所涉及的知識點在進行深入。
知識改變命運