2010-12-23 24 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秒刷新一次。由于部署需要一分钟,似乎解决了这个问题。

相关问题