2010-12-23 49 views
12

這可能不是MVC特有的,它可能也適用於ASP.NET WebForms,但我們在MVC2上已經體驗過它。使用組件化ASP.NET MVC應用程序可以順利部署嗎?

每當我們開始使用MSDeploy進行遠程部署時,我們都會爲我們的請求獲取一個簡短的(服務器錯誤)頁面(5-6秒),直到發生新的部署。以下是錯誤文本:

'/'應用程序中的服務器錯誤。

無法加載文件或程序集 'Some.Assembly'或其某個 依賴項。該進程不能 訪問該文件,因爲它正在被其他進程使用的 。 (異常 從HRESULT:0x80070020)

描述:未處理的異常 的 當前web請求的執行過程中發生。請查看 堆棧跟蹤以瞭解有關 錯誤的更多信息,以及它源自 的代碼。

異常詳細信息: System.IO.FileLoadException:無法 載荷文件或程序集Some.Assembly' 或它的一個依賴。 進程無法訪問該文件,因爲 它正在被另一個進程使用。 (來自HRESULT的例外:0x80070020)

版本信息:Microsoft .NET Framework版本:4.0.30319; ASP.NET 版本:4.0.30319.1

以下是錯誤頁面顯示的堆棧跟蹤:

[FileLoadException: Could not load file or assembly 'Some.Assembly' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] 
    System.Reflection.RuntimeAssembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +0 
    System.Reflection.RuntimeAssembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, RuntimeAssembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection, Boolean suppressSecurityChecks) +39 
    System.Reflection.RuntimeAssembly.InternalLoadAssemblyName(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection, Boolean suppressSecurityChecks) +132 
    System.Reflection.RuntimeAssembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection) +144 
    System.Reflection.Assembly.Load(String assemblyString) +28 
    System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +46 

[ConfigurationErrorsException: Could not load file or assembly 'Some.Assembly' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] 
    System.Web.Configuration.CompilationSection.LoadAssemblyHelper(String assemblyName, Boolean starDirective) +618 
    System.Web.Configuration.CompilationSection.LoadAllAssembliesFromAppDomainBinDirectory() +209 
    System.Web.Configuration.CompilationSection.LoadAssembly(AssemblyInfo ai) +130 
    System.Web.Compilation.BuildManager.GetReferencedAssemblies(CompilationSection compConfig) +178 
    System.Web.Compilation.BuildManager.GetPreStartInitMethodsFromReferencedAssemblies() +94 
    System.Web.Compilation.BuildManager.CallPreStartInitMethods() +332 
    System.Web.Hosting.HostingEnvironment.Initialize(ApplicationManager appManager, IApplicationHost appHost, IConfigMapPathFactory configMapPathFactory, HostingEnvironmentParameters hostingParameters, PolicyLevel policyLevel, Exception appDomainCreationException) +591 

[HttpException (0x80004005): Could not load file or assembly 'Some.Assembly' or one of its dependencies. The process cannot access the file because it is being used by another process. (Exception from HRESULT: 0x80070020)] 
    System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +8950644 
    System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +97 
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +256 

這是造成該故障(Some.Assembly)大會是不實際的網頁組件,但其中的一個組件是它的「參考」,用.snk進行簽名。

經過5-6秒後,網站上升,錯誤消失。

這當然不是理想的行爲。我想知道我們是否在組件連接方面做錯了什麼。是否應該有另一種方法來確保順利部署?或者這可能是MVC2本身的錯誤?

P.S.無論如何,IIS重疊旋轉是啓用的。

以下是組分:

  • A.DLL
  • Some.Assembly.dll(< ---這是發生故障的一個,取決於A.DLL)
  • B.DLL(取決於A.dll和Some.Assembly.dll)
  • Web。dll(這是網絡應用程序,取決於上述所有內容)

所有的依賴關係都是使用啓用Copy Local的常規程序集引用來建立的。所有的DLL都是解決方案的一部分,作爲單獨的項目。

MSDeploy僅部署二進制文件,而不是源文件。

+0

顯示你如何組成網站將有所幫助。 – jfar 2010-12-23 17:55:30

+0

@jfar:完成了。 – 2010-12-23 18:04:44

+0

所以你不在運行時加載組件? – jfar 2010-12-23 18:27:11

回答

20

重疊旋轉僅適用於池回收,並不旨在簡化您所描述或要求的部署類型。當啓用重疊循環時,池中的「外發」工作進程中的現有請求將被允許完成,而新的請求將被髮送到創建的新工作進程。這是一種適當切換到新工作流程的機制,無需將現有請求下的地毯拉下來。就是這樣。

卷影複製文件夾被用於此目的:

What is the 「Temporary ASP.NET Files」 folder for? (My Answer)

他們再次不打算提供一種機制,以便保持整個現有的代碼庫運行,同時您上傳新網站。

當您部署ASP.NET應用程序時,該網站行爲不端。當你正在複製你的程序集時,這些文件將被處理上傳(WebDAV或FTP)的任何進程鎖定(可能是唯一的)。

這會導致您觀察到的異常,很可能是因爲卷影複製機制在寫入之前無法讀取新程序集(並且WebDAV或FTP刪除了寫入鎖定)。

此外,如果預期的方法簽名已更改或被刪除,直到上傳正確的頁面,則對這些程序集有依賴關係的任何頁面可能無法(陰影)編譯。或者,如果首先上傳的頁面/視圖依賴於尚未部署的程序集中的功能,那麼您也會收到錯誤。

整個站點將處於不一致的狀態,直到部署最後一個文件。

在IIS中沒有內置的機制來確保「原子」部署,即加載所有的東西然後切換到運行。 IIS將繼續向網站提供服務請求,並且在您上傳應用程序時,ASP.NET仍會繼續檢測文件更改。

在不產生這些錯誤,這是使部署之前稱爲App_Offline.htm一個特殊的頁面,然後重命名或部署後刪除部署應用程序的唯一方法:

App_Offline.htm - Scott Guthrie
App_Offline.htm and working around the "IE Friendly Errors" feature

您也可能會發現這篇文章很有用:

How to: Prepare to Deploy a Web Project

,還有一種涉及有兩個文件夾,例如一個稍微令人費解的選擇:

d:\websites\site\www-A d:\websites\site\www-B

運行的網站指向d:\websites\site\www-A,同時部署到d:\websites\site\www-B。當你準備好時,你將網站切換到d:\websites\site\www-B文件夾。

當您開始部署下一個內置部件時,您可以將其部署到d:\websites\site\www-A,並在您滿意時切換到該部件。

缺點是你需要在腳趾上,並記住哪個文件夾是哪個。

此外,任何用戶上傳的內容都需要在兩個文件夾之間同步(儘管您可以將第三個文件夾映射到虛擬目錄中)。

2

我的部署腳本停止網站,並顯示「正在更新網站正在更新...」頁面,該頁面每15秒刷新一次。由於部署需要一分鐘,似乎解決了這個問題。

相關問題