如何部署ASP.NET应用程序,零停机时间

Kar*_*non 126 asp.net deployment iis redundancy

要部署我们网站的新版本,我们执行以下操作:

  1. 压缩新代码,并将其上传到服务器.
  2. 在实时服务器上,从IIS网站目录中删除所有实时代码.
  3. 将新代码zipfile解压缩到现在空的IIS目录中

这个过程都是脚本化的,并且发生得非常快,但是当旧文件被删除以及部署的新文件时,仍然会有10-20秒的停机时间.

关于0秒停机时间方法的任何建议?

Skl*_*vvz 79

您需要2台服务器和一台负载均衡器.这是步骤:

  1. 关闭服务器2上的所有流量
  2. 在服务器1上部署
  3. 测试服务器1
  4. 关闭服务器1上的所有流量
  5. 在服务器2上部署
  6. 测试服务器2
  7. 打开两台服务器上的流量

事情是,即使在这种情况下,如果您使用"粘性会话",您仍然会重新启动应用程序并丢失会话.如果你有数据库会话或状态服务器,那么一切都应该没问题.

  • 当代码卷对数据库进行结构更改时,此方法会降低.升级服务器1的数据库后,服务器2将爆炸.现在,您可以备份/还原数据库以便在服务器1上进行测试,但是在运行并行副本时,您遇到了在实时数据库中更改数据的问题. (34认同)
  • @EBarr:在任何情况下*技术上*在ASP.NET应用程序上仍然没有停机时间 - 问题不在于"如何部署到没有停机时间的sql server db". (9认同)
  • 它们的关键是以一种你的sql更改不具有破坏性的方式开发.一旦不再使用,您通常必须在以下版本中进行任何破坏性的sql更改.练习并不难. (6认同)
  • 您还可以配置负载均衡器,以便为给定服务器提供现有会话服务,但不接受新服务器.这样可以避免丢弃会话.然而,这种技术需要等待会话结束,通常你会想要编写脚本. (4认同)

Geo*_*kos 60

微软Web部署工具支持这种在一定程度上:

启用Windows事务文件系统(TxF)支持.启用TxF支持时,文件操作是原子操作; 也就是说,它们要么成功要么完全失败.这可确保数据完整性并防止数据或文件以"中途"或损坏状态存在.在MS Deploy中,默认情况下禁用TxF.

似乎交易是针对整个同步的.此外,TxF是Windows Server 2008的一项功能,因此此事务功能不适用于早期版本.

我相信可以使用文件夹作为版本和IIS元数据库来修改脚本的0停机时间:

  • 对于现有路径/网址:
  • 将新(或修改过的)网站复制到服务器下
    • \网络\程序\ 2.1 \
  • 修改IIS元数据库以更改网站路径
    • 来自\web\app\2.0 \
    • \web\app\v2.1 \

此方法具有以下优点:

  • 如果新版本出现问题,您可以轻松回滚到v2.0
  • 要部署到多个物理或虚拟服务器,可以使用脚本进行文件部署.所有服务器都具有新版本后,您可以使用Microsoft Web部署工具同时更改所有服务器的配置数据库.

  • 不幸的是,这种方法没有考虑到DB的结构变化.升级数据库for v2.1后,v.2.0将爆炸. (17认同)
  • IMO,使用TxF在这里有点过头了.同时在文件系统中同时拥有v2.0和v2.1并不会造成任何损害.当v2.1上线时发生了重大变化,到那时,TxF事务已经提交.由于IIS从旧的AppPool移动到新的AppPool,而不是因为TxF,因此实现零停机. (8认同)
  • 我通过调整我们的PowerShell部署脚本实现了这种方法.您可以在此处看到更改IIS站点文件夹的脚本部分:http://stackoverflow.com/questions/330608/changing-iis6-site-home-directory-with-powershell-answered感谢指针. (5认同)
  • 另一个问题是,如果大量用户数据存储在app文件夹的子文件夹中. (5认同)
  • 这不是0秒部署,因为新应用程序需要启动. (4认同)

kav*_*vun 12

通过将IIS中的应用程序请求路由用作不同端口上两个本地IIS站点之间的软件负载平衡器,您可以在单个服务器上实现零停机部署.这称为蓝绿色部署策略,在任何给定时间,负载均衡器中只有两个站点中的一个可用.部署到"关闭"的站点,将其加热并将其带入负载均衡器(通常通过传递应用程序请求路由运行状况检查),然后从"池"中取出已启动的原始站点(再次通过使其健康检查失败).

可在此处找到完整的教程.


小智 7

我最近经历了这个,我想出的解决方案是在IIS中设置两个站点并在它们之间切换.

对于我的配置,我有一个每个A和B站点的Web目录,如下所示:c:\ Intranet\Live A\Interface c:\ Intranet\Live B\Interface

在IIS中,我有两个相同的站点(相同的端口,身份验证等),每个站点都有自己的应用程序池.其中一个站点正在运行(A),另一个站点正在运行(B).live live也有实时主机头.

在部署到生活时,我只是发布到STOPPED站点的位置.因为我可以使用其端口访问B站点,所以我可以预热站点,以便第一个用户不会导致应用程序启动.然后使用批处理文件我将实时主机头复制到B,停止A并启动B.

  • @Ebarr然后不推出破坏性的SQL更改.例如,如果您需要删除列,请在下一个版本中执行此操作,此时A或B不再使用该列. (3认同)
  • @Rob如果网站被停止你如何"预热"该网站? (2认同)
  • @Rob“将实时主机头复制到B”你能解释一下吗? (2认同)

Jac*_*ack 7

使用Microsoft.Web.Administration的ServerManager类,您可以开发自己的部署代理.

诀窍是更改VirtualDirectory的PhysicalPath,这将导致新旧Web应用程序之间的在线原子切换.

请注意,这可能会导致新旧AppDomain并行执行!

问题是如何将更改同步到数据库等.

通过使用旧的或新的PhysicalPaths轮询AppDomains的存在,可以检测旧的AppDomain何时终止,以及新的AppDomain是否已启动.

要强制AppDomain启动,您必须发出HTTP请求(IIS 7.5支持自动启动功能)

现在,您需要一种方法来阻止对新AppDomain的请求.我使用一个名为mutex - 由部署代理创建和拥有,由新Web应用程序的Application_Start等待,然后在部署数据库更新后由部署代理发布.

(我在Web应用程序中使用标记文件来启用互斥等待行为)一旦新的Web应用程序运行,我删除标记文件.


mik*_*son 6

好的,因为每个人都在贬低我在2008年写回来的答案*...

我将在2014年告诉您我们是如何做到的.我们不再使用网站,因为我们现在正在使用ASP.NET MVC.

我们当然不需要负载均衡器和两台服务器来做这件事,如果你为你维护的每个网站都有3台服务器,那就没问题了,但对于大多数网站而言,它总是过度杀伤.

此外,我们不依赖于微软的最新向导 - 太慢,太多隐藏的魔法,而且太容易改变它的名字.

我们是这样做的:

  1. 我们有一个post build步骤,它将生成的DLL复制到'bin-pub'文件夹中.

  2. 我们使用Beyond Compare(非常好**)来验证和同步已更改的文件(通过FTP,因为它得到广泛支持)直到生产服务器

  3. 我们在网站上有一个安全的URL,其中包含一个按钮,可以将'bin-pub'中的所有内容复制到'bin'(首先进行备份以启用快速回滚).此时,应用程序将重新启动.然后我们的ORM检查是否有任何需要添加的表或列并创建它们.

这只是几毫秒的停机时间.应用程序重新启动可能需要一两秒钟,但在重新启动期间请求被缓冲,因此实际上没有停机时间.

整个部署过程需要5秒到30分钟,具体取决于更改的文件数量和要审核的更改数量.

这样您就不必将整个网站复制到不同的目录,只需复制bin文件夹.您还可以完全控制流程,并确切知道正在发生的变化.

**我们总是快速了解我们正在部署的更改 - 作为最后一分钟的双重检查,因此我们知道要测试什么,如果有什么破坏我们准备好了.我们使用Beyond Compare,因为它可以让您轻松地通过FTP传播文件.没有BC,我永远不会这样做,你不知道你在覆盖什么.

*滚动到底部查看它:(顺便说一句,我不再推荐网站,因为它们构建速度较慢,并且可能会因为一半编译的临时文件而崩溃.我们过去使用它们因为它们允许更加灵活的逐个文件很快就可以解决一个小问题,你可以看到你正在部署什么(如果当然使用Beyond Compare - 否则就算了).


Sam*_*rum 5

我能想到的唯一零停机方法涉及托管至少2台服务器.