我正在尝试将 .NET Web 应用程序部署到 IIS (7.5),而不会给用户带来任何麻烦。我已经确定禁用重叠回收为假,但我每次仍然遇到同样的问题。
每次我为站点上传新的二进制文件时,IIS 都会在启动新的工作进程之前终止该工作进程。因此,每次我上传新的二进制文件时,用户都会收到此错误消息:
“/”应用程序中的服务器错误。可以
不加载文件或程序集
“MyApplicationWeb”或其之一
依赖关系。该过程不能
访问该文件,因为它正在
被另一个进程使用。 (例外
来自 HRESULT:0x80070020)
我不知道如何无缝地做到这一点。现在我只是上传二进制文件;但是当上传发生(或本地副本)时,它将给出上述行为。我也尝试过使用网络花园,但结果相同。
我不寻找什么:
- 如何使用外部负载平衡器解决它(这是一个功能性解决方案,但从性能角度来看,对于少数服务器而言,这是一个糟糕的解决方案,如果只有一台服务器,它根本无法工作)
- 如何创建黑客- 在自定义错误页面中进行刷新(因为它有一些明显的问题,但更重要的是根本无法与 Web 服务/ajax 一起使用)。
我真的认为这应该是可行的 http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
更新:
在上面的文章中他们说:
但是因为关机超时
关闭或启动的值为
可配置,工作进程可以
趁它还在的时候被终止
如果未完成则处理请求
为现有请求提供服务
时间限制。
我不知道在哪里可以找到这个值,也不知道它的默认值是什么。如果它少于几秒钟,它可能会解释我的结果。
附注我将其发布在 SO 上,而不是在 SF/网站管理员等上,因为我认为对于不积极参与开发的人来说,这种知识可能很少,我希望这没问题。
I am trying to deploy a .NET Web application to IIS (7.5) without any hassle for the users. I have made sure that Disable Overlapped Recycle is False but i still run into the same problem every time.
Every time I upload new binaries for the site, IIS kills the worker process before it has started a new one. So every time I upload new binaries users get this error message:
Server Error in '/' Application. Could
not load file or assembly
'MyApplicationWeb' or one of its
dependencies. The process cannot
access the file because it is being
used by another process. (Exception
from HRESULT: 0x80070020)
I have no idea how to do this seamless. As it is now I just upload the binary; but while the upload occurs (or local copy) it will give the above quoted behaviour. I also tried using a Web garden but with same result.
What I am not looking for:
- How to solve it with external load balancers (it's a functional solution but it is perfomance wise a bad solution for few servers and it won't work at all if there's only one server)
- How to create a hack-around with a refresh in a custom error page (as it has some obvious problems but more importantly wont work at all with web services/ajax).
I really think this should be doable given http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/24e3c22e-79a9-4f07-a407-dbd0e7f35432.mspx?mfr=true
Update:
In article above they say:
However, because the shutdown timeout
value of a shutdown or startup is
configurable, the worker process can
be terminated while it is still
serving requests if it does not finish
servicing existing requests within the
time limit.
I have no idea where to find this value nor what it's default. If its less then a few second it might explain my results.
ps. I am posting it on SO rather than on SF/Webmasters etc because I think this kind of knowledge will probably be minimal amongst people who aren't active in development, I hope this is all right.
发布评论
评论(5)
部署 ASP.Net 应用程序时,我在服务器上创建一个新文件夹,并更改 IIS 中网站的主目录。这提供了零停机部署和快速回滚位置,以防出现不可预见的问题。在将来的更新中,我废弃旧版本并重复该过程,以便始终有一个回滚位置。
更新 - 关闭时间限制
配置工作人员关闭时间限制的详细信息位于 http ://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel。默认值为 1 分 30 秒。在链接页面中查找 shutdownTimeLimit 部分。
更新 - 更多信息
类似的问题有一个很好的答案
其要点是,由于覆盖现有文件,复制机制对文件采取独占锁定,并且如果不使用 app_offline.htm 或上面建议的机制,就不可能实现无缝部署。阅读链接的答案,因为它会更深入。
When deploying ASP.Net applications I create a new folder on the server and change the home directory of the website within IIS. This provides zero downtime deployment and a quick rollback position in case of unforeseen issues. On a future update I scrap the old version and repeat the process so that there is always a single rollback position.
Update - Shutdown time limit
Details configuring the shutdown time limit for workers is detailed at http://www.iis.net/ConfigReference/system.applicationHost/applicationPools/add/processModel. The default is 1 min 30 secs. Look for the shutdownTimeLimit section in the linked page.
Update - More information
Similar question with a great answer
The gist of this is that the due to overwritting the existing files the copying mechanism takes an exclusive lock on the files and that it is not possible to have seemless deployment without use of app_offline.htm or a mechanism such as suggested above. Take a read of the linked answer as it goes into much more depth.
我同意 Smirkin 的回应 - 更新第二个文件夹并更改 IIS 主目录以指向另一个文件夹。这样做的另一个优点是您有一个简单的回滚路径(只需将 IIS 主目录切换回来)。
我写了一篇带有脚本的帖子,介绍如何使用 Powershell 执行此操作 - 希望它有所帮助: http://davidduffett.net/post/4833657659/blue-green-deployment-to-iis-with-powershell
您应该能够直接从持续集成中使用此脚本系统。
I agree with Smirkin's response - updating a second folder and changing the IIS home directory to point to the other folder. Another advantage to this is that you have an easy rollback path (just switch the IIS home directory back).
I've written a post with a script on how to do this using Powershell - hope it helps: http://davidduffett.net/post/4833657659/blue-green-deployment-to-iis-with-powershell
You should be able to use this script directly from your continuous integration system.
Smirkin 的答案为管理员提供了一种很好的无缝方式,可以在很少或没有停机时间的情况下部署站点,并且如果您在代码库中进行了重大更改(即删除旧页面,更改表单等),那么对于在切换之前启动进程并在切换之后完成进程的任何用户来说,使用此方法仍然可能会带来一些“麻烦”(即,他们在切换之前请求一个页面,开始填充,然后在切换到新目录后提交页面)。
我知道您不想让我这么说,但是如果没有启用粘性会话的负载平衡器,您将无法允许人们继续使用旧版本的网站,直到他们在处理新版本时完成新版本上的会话 - 通过更改应用程序的主目录,IIS 将重新编译应用程序并重新启动进程。通过这种方式,您可以将旧服务器设置为继续为其当前连接提供服务,但告诉负载平衡不要向其发送任何新连接。
不过,您还可以采取另一个步骤来帮助缓解与此相关的常见问题:
配置 MachineKey 是一个常量值,而不是
AutoGenerate
- 这意味着当 AppPool 回收时,它将使用相同的密钥,因此能够解密会话cookie、视图状态等。Whilst Smirkin's answer provides a nice seamless way for an Admin to deploy a site with little or no downtime, and should resolve your issue with missing assemblies/references, if you have breaking changes in your code-base (i.e. removing old pages, changes to forms, etc.), then using this method could still result in some "hassle" for any users who start a process before the switch and complete it after the switch (i.e., they request a page before you switch over, start filling it in, and then submit the page after you've switched over to the new directory).
I know you don't want me to say this, but without a load-balancer with Sticky-Sessions enabled, you won't be able to allow people to continue using the old version of the site until they've finished while handling new sessions on the new version - by changing the home directory of the application, IIS will perform a re-compile of the app and restart the processes. This way you can set the old server to continue serving its current connections, but tell the load-balance not to send any new connections to it.
There is however another step you can take to help mitigate the issues often seen around this:
Configure the MachineKey to be a constant value rather than
AutoGenerate
- this means that when the AppPool recycles it will use the same key, and so be able to decrypt session cookies, viewstate, etc.我的猜测是,您有一个病毒扫描程序或某种其他类型的索引进程,一旦您将文件复制到那里,它就会锁定该文件。
My guess is that you have a virus scanner or some other kind of indexing process that it locking the file as soon as you copy it out there.
您可以使用app_offline.htm,
这个解决方案不是无缝的,但是您可以
在htm文件中使用a,这样浏览器就会自动刷新,而不需要任何javascript。
干杯
you could use app_offline.htm
this solution is not seamless, but you could use a
in the htm file, so the browser automatically refreshes the without any javascript.
cheers