Core在IIS的熱釋出問題或者報錯檔案已在另一個程式中開啟

Hyman.Zheng發表於2020-12-06

關於Core釋出到IIS的熱釋出問題,或者覆蓋dll檔案的時候會報錯"檔案已在另一個程式中開啟",也就是無法覆蓋程式的問題,經過百度和分析總結以下幾種方案:

一、使用app_offline.htm檔案,這個方案網上最多:

1.具體步驟:

1)在釋出路徑新建一個資料夾"UpdateFiles"

2)資料夾"UpdateFiles"裡面放一個app_offline.htm檔案,這個檔案是網站處於離線狀態的時候的返回給客戶端的頁面內容

3)資料夾"UpdateFiles"裡面放一個"PublishFiles"資料夾,這個資料夾裡面放需要釋出的檔案

4)在釋出路徑下面新建一個"pubish.bat"檔案,裡面輸入如下內容:其實就是先複製app_offline.htm檔案到釋出路徑,讓網站處於離線狀態,然後覆蓋釋出的檔案,再刪除pp_offline.htm檔案,讓網站恢復線上狀態

@echo off
call xcopy %~dp0UpdateFiles\app_offline.htm %~dp0
call xcopy %~dp0UpdateFiles\PublishFiles %~dp0 /s /e /Y
del %~dp0app_offline.htm
pause

2.利弊分析:

好處:

1.實現簡單

2.不用開發

弊端:

1.複製app_offline.htm檔案到釋出路徑之後,網站不能立即結束,需要等最後的請求結束,才能複製,不然以上指令碼複製的時候會失敗

2.複製app_offline.htm檔案到釋出路徑之後,時沒有結束的請求返回的結果會最終會是空白內容,也即會是失敗,這樣會造成客戶端釋出的時候偶發性的失敗問題

3.覆蓋檔案期間,網站處於離線狀態,無法正常訪問

二、改檔名字,然後複製釋出程式,然後退出網:

來源:https://bbs.csdn.net/topics/395986630

1.具體步驟:

如下程式碼,在一個控制器建立一個如下的方法,然後需要更新的時候Post這個方法就行。以下程式碼沒有具體測試過,只測試過可以修改檔名字和application.StopApplication();會退出網站,所以應該是可行的。

 [HttpPost]
        public IActionResult Update([FromServices]IHostApplicationLifetime application)
        {
            //獲取程式的工作目錄路徑,依賴注入 IWebHostEnvironment
            var web = WebHost.ContentRootPath;
 
            //// 改名方法-假設專案的dll 為 WebApplication1.dll
            FileInfo fi = new FileInfo(Path.Combine(web, "WebApplication1.dll"));
            //// 改為 a1234
            fi.MoveTo(Path.Combine(web, "a1234.dll"));
 
            //要複製的新檔案路徑-你的新dll 路徑 可以是下載或者複製或移動
            string pLocalFilePath = Path.Combine(WebHost.WebRootPath, "css", "WebApplication1.dll");
 
            //將新檔案複製過去基目錄
            string pSaveFilePath = Path.Combine(web, "WebApplication1.dll");
            if (System.IO.File.Exists(pLocalFilePath))
            {
                System.IO.File.Copy(pLocalFilePath, pSaveFilePath, true);
 
                //複製成功後, 殺死當前的程式=相當於重啟了  依賴注入 IHostApplicationLifetime
                application.StopApplication();
            }
 
            return Content("ok");
        }

2.利弊分析:

好處:

1.基本可以實現IIS的熱釋出

弊端:

1.application.StopApplication();之後,當時沒有結束的請求返回的結果會最終會是空白內容,也即會是失敗,這樣會造成客戶端釋出的時候偶發性的失敗問題

2.現稍微複雜,需用開發

三、使用Consul這種服務管理軟體(推薦):

1.具體實現:

這個還沒有來得及具體去Ⅹ,不過理論上是比較完美的解決方案,但實現起來有點複雜,其實就是利用Consul的高可用功能來實現,可以IIS中部署2個相同的網站服務,然後釋出的時候一個個釋出更新網站,更一個的時候,贊停另一個,這樣就可以在不影響客戶端的情況下更新網站了。當然也可以用多伺服器來實現高可用。

2.利弊分析:

好處:

1.比較完美的實現熱釋出,實現高可用

弊端:

1.需要搭建Consul,部署2個或多個網站

 

本來剛接觸Core,希望有經驗的大佬推薦更加完善的解決方案。

相關文章