Shadow Copying in IIS - 不停機更版

使用紀錄, ShadowCopying, 部版小技巧, .NET6, web.config

不停機更版

不停機更版是軟體更版人員的天堂。

以 IIS Web App 為例,全手動更版傳統上一定要停機。若不停機就要導入 app_offline.htm 更新程序,在這個更新過程網站其實是半關機狀態,欲更新的部份將回應 503-授權不足。

若經由 WebDeploy 等自動部版工具也能不停機更版,但在實務上全手動更版仍是主要手段。

微軟又研發了 Shadow Copying in IIS 的機制可以全手動不停機更版。

手動更版問題

手動更版問題,以 IIS Web App 為例,因為網站未停止所以 DLL 檔被鎖住的問題。

網站未停止所以 DLL 檔被鎖住

舊的解法

使用 app_offline.htm (半)關閉網站

其實一直以來,微軟官方建議的更新手段,是在網站根目錄加上 app_offline.htm 檔案,強迫關閉應用程式集區。但是這種更新方法會導致網站在更新部署的過程中無法提供服務,以致於網站中斷服務,回應 503-授權不足,所以一直不是很理想的部署方法。

app_offline.htm 使用方式

  1. 在網站根目錄中加入 App_offline.htm

    App_offline.htm 內容以 html 語法編輯

  2. 更新網站內容

  3. 移除 App_offline.htm

新的解法 - Shadow Copying in IIS

前提要件

  1. .NET6+ 才有的功能。(其實是在 .NET7 開發出來後又加回到 .NET6)

  2. 安裝包已隨附在 Windows Server Hosting 內。

過程紀錄

在 Windows 11 的 IIS 測試有啟動紀錄但無效果。在 Windows Server 2019 測試有效。

步驟只有一個在 Web.config 加入 experimentalEnableShadowCopy 的組態段落就行了。

手動更版的標的仍是目標網站實體目錄。之後 Shadow Copying 機制會自動運作。

Web.config 啟動 Shadow Copying

Web.config 在發佈時會自動產生預設檔,請手動修改啟動 shadow copying 能力。

Web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <remove name="aspNetCore"/> <!-- #先移除再加入以確保更新組態 -->
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\MyAppNameHere.dll" stdoutLogEnabled="false" hostingModel="InProcess" stdoutLogFile=".\logs\stdout">
        <environmentVariables>
          <!-- # 設定環境參數(一般不需要) -->
          <!-- <environmentVariable name="ASPNETCORE_HTTPS_PORT" value="8443" /> -->
          <!-- <environmentVariable name="ASPNETCORE_ENVIRONMENT" value="Development" /> -->
        </environmentVariables>
        <handlerSettings>
          <!-- # 啟用 Shadow Copying -->
          <handlerSetting name="experimentalEnableShadowCopy" value="true" />
          <handlerSetting name="shadowCopyDirectory" value="../MyAppNameHere_Shadow/" />
          <!-- Only enable handler logging if you encounter issues -->
          <!-- <handlerSetting name="debugFile" value="../ShadowCopyLogs/aspnetcore-debug.log" /> -->
          <!-- <handlerSetting name="debugLevel" value="FILE,TRACE" /> -->
        </handlerSettings>
      </aspNetCore>
    </system.webServer>
  </location>
</configuration>

※ Shadow Copying in IIS 重要特性

  1. Shadow Copying in IIS 將複製一份完整的『網站陰影』到『ShadowCopyDirectory』目錄。

  2. 『ShadowCopyDirectory』目錄內的『網站陰影』會自動管理,請不要介入操作。

  3. 各系統的『ShadowCopyDirectory』目錄需各自獨立。在多系統『網站陰影』情境下會有更新螺旋現象,導致出現 500.30 錯誤代碼回應。

  4. 再之後過期的『網站陰影』將會自動刪除,請不要介入操作。

  5. 依據測試,似乎只在 Windows Server 2019+ 伺服器以上版上才有效。 在Windows 11 有啟動但沒有效果。

  6. 依據測試,複製檔案的權限也要滿足的樣子。

  7. 依據測試, Shadow Copying 更版期間(主機端)是斷線狀態,完成後自動變成新版。若是小幅度的更版採用不停機更版應該是無妨的;大幅度的更版建議還是停機更版,過程中可以做更多的測試確認比較可靠。

測試紀錄:on 23-9-11

想更了解 Shadow Copying 過程中的 Fuzy 狀態,決定設計線上操作線上更新的情境。系統框架為 Blazor Server App,在線上有人正在操作的情境下進行 Shadow Copying 更版,在這期間畫面操作直接斷線,過一陣子重新刷新畫面就變成新版畫面了。整理一下過程,無縫更版是不存在的,就算是不停機更新系統還是會中斷一小時間。若是小幅度的更版採用不停機更版應該是無妨的;大幅度的更版建議還是停機更版比較可靠過程中可以做更多的測試確認。

觀察紀錄

on 23-9-8

二個系統共用『ShadowCopyDirectory』目錄發現網站有 500.30 錯誤代碼回應,然在幾分鐘後,什麼處置動作都沒下,就又可以正常開啟了,猜測在 shadow copying 機制下網站仍有一小段 fuzy 狀態在處理同步網站內容吧。

on 23-9-11

二個系統共用『ShadowCopyDirectory』目錄再度發現二個網站都是 500.30 錯誤代碼回應,這兩個網站並未有任何更版。決定停機分拆各自獨的的『ShadowCopyDirectory』目錄後重新啟動網站就可以正常打開網站了。推測各網站的『ShadowCopyDirectory』目錄是不能共用的。 觀察現象2:明明二個網站都沒有更版但『ShadowCopyDirectory』目錄卻多昇了幾個版號。推測多系統共用『ShadowCopyDirectory』目錄狀況下會觸發更版。推測是A網站認為B網站的『網站陰影』是它的新版所以觸發了更新程序;之後B網站又認為A網站的『網站陰影』是它的新版所以又觸發了更新程序,彼此變成不斷的更新螺旋造成系統不正常。

沒圖沒真像

『ShadowCopyDirectory』目錄內的『網站陰影』以數字序號放置,請不要介入操作,讓Shadow Copying 機制會自動運作就好。

參考文章

(EOF)

Last updated