簡體   English   中英

IIS 發布 ASP.NET 核心應用程序而不關閉 IIS 網站

[英]IIS Publish ASP.NET Core App Without Bringing Down IIS Website

當前設置


我們目前將 ASP.NET 核心產品部署到:

  • Windows 服務器 2016
  • 托管在 IIS 版本 10.0.14393.0

我們有一個“站點”,下面有多個應用程序。 每個應用程序都使用自己的應用程序池並映射到不同的物理文件夾路徑位置。

每個應用程序都由其自己的源代碼 ASP.NET Core Server 項目表示

IIS結構

站點中子應用程序的 IIS 結構

問題


我們的 CI/CD 使用 Jenkins,這是無法更改的。 我們有 Powershell 腳本與 IIS 交互

沒有 IIS 命令來停止應用程序,只有站點,但理想情況下,我們不希望在發布單個應用程序的新版本時關閉站點。 我們只想關閉那個特定的應用程序。

我們通過停止與應用程序關聯的 WebAppPool 來嘗試此操作,然后等待(2 分鍾......然后 5 分鍾)。 但即使在那之后,應用程序文件仍然被鎖定。

我們最終關閉了 WebAppPool 和站點以釋放文件,以便可以替換它們。

我知道必須有更好的方法來做到這一點。 我們如何關閉單個應用程序並阻止新請求到達它,以便我們可以替換文件然后重新啟動它? 一直以來,“SITE”及其下未更新的任何其他應用程序仍在運行。 我不介意更新應用程序的停機時間。

2022 年 6 月 8 日更新

找到這個: https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/app-offline?view=aspnetcore-6.0

去看看這是否能解決我的問題。

在應用程序的根文件夾中添加名為 app_offline.htm 的文件應該會強制 ASP.NET Core 模塊關閉應用程序並停止處理傳入請求。 然后,您應該能夠在不影響其他應用程序的情況下部署新文件。

我強烈建議使用帶有 IIS 的Web 部署 設置起來有點麻煩,但是一旦配置好,它就真的很好用。

如果您以這種方式發布,它將自動執行以下操作:

  • 繼續接受傳入的請求,但暫停它們
  • 優雅地停止舊版本的應用程序
  • 回收應用程序池
  • 啟動新版本的應用程序
  • 暫停的請求將恢復到新版本的應用程序

此解決方案使您能夠部署新版本,而不會對您的服務造成明顯的中斷,而其他解決方案可能會在發布期間使您的服務無法訪問。

我只使用了 Visual Studio 的發布菜單,但應該可以通過調用 msbuild.exe 的 CI/CD 腳本使其工作,如此處所述 (鏈接描述了 TeamCity 的靈魂,但應該可以適應 Jenkins)

我以前成功地將 IIS 中的站點指向符號鏈接。 然后,符號鏈接又指向一個包含網頁內容的文件夾。

每當我必須更新網頁時,我都會創建一個新文件夾,將其命名為webpage_date,然后更新符號鏈接並將其指向新文件夾。 最后我回收了負責網頁的 AppPool。

所以它會去:

符號鏈接 -> 網頁_1

將帶有更新網頁的文件夾放在旁邊,稱為webpage_2。 指向它的符號鏈接:

符號鏈接 -> 網頁_2

然后回收 AppPool。

這使得停機時間非常短。

重啟 WebAppPool 的 Powershell 命令:

Restart-WebAppPool -Name "YourAppPool"

重啟-WebAppPool 文檔

可以使用創建符號鏈接

New-Item -ItemType SymbolicLink -Path .\link -Target .\Notice.txt

Powershell 新項目符號鏈接文檔

這是我使用藍/綠策略的方法:

首先,我在服務器上創建了這個文件夾結構:

 D:\inetpub\wwwroot\MyAppPath\ Staging Green Blue

接下來,在 IIS 中,我將應用程序的物理路徑指向 D:\inetpub\wwwroot\MyAppPath\Green

然后我創建了 D:\inetpub\wwwroot\MyAppPath\SetAppPath.ps1

($curPath = Get-WebFilePath -PSPath "IIS:\Sites\www.example.com\MyApp")
if ($curPath -like "*Blue*") {
    Copy-Item -Path "D:\inetpub\wwwroot\MyAppPath\Staging\*" -Destination "D:\inetpub\wwwroot\MyAppPath\Green" -Recurse -Force
    Set-ItemProperty IIS:\Sites\www.example.com\MyApp -name physicalPath -value "D:\inetpub\wwwroot\MyAppPath\Green"
} else {
    Copy-Item -Path "D:\inetpub\wwwroot\MyAppPath\Staging\*" -Destination "D:\inetpub\wwwroot\MyAppPath\Blue" -Recurse -Force
    Set-ItemProperty IIS:\Sites\www.example.com\MyApp -name physicalPath -value "D:\inetpub\wwwroot\MyAppPath\Blue"
}

然后,我創建了一個沒有運行 SetAppPath.ps1 的觸發器的任務 (SetMyAppPath)

在我的開發工作站上,我在項目根目錄中創建了 deploy.ps1:

param ($buildType)
net use r: /delete
dotnet publish --configuration $buildType
net use R: "\\111.222.333.444\d`$" /user:"MyAdminUser" "MyAdminPassword"
Copy-Item -Path "C:\Users\MyUser\Dir1\Dir2\Dir3\MyProject\bin\$buildType\netcoreapp3.1\publish\*"  -Exclude web.config,appsettings.json,appsettings.Development.json -Destination "R:\inetpub\wwwroot\MyAppPath\Staging" -Recurse -Force
schtasks /RUN /S \\111.222.333.444 /U MyAdminUser /P MyAdminPassword /tn SetMyAppPath
net use r: /delete

然后,為了部署,我運行。\Deploy Debug 或.\Deploy Release

因此,當我准備好部署新版本時,會將文件復制到服務器上的暫存文件夾中。 然后,服務器上的任務被觸發,該任務將暫存文件復制到綠色或藍色文件夾,該文件夾不是當前文件夾。

最后,應用程序路徑將更新為綠色或藍色文件夾,這不是當前文件夾。

奇跡般有效。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM