我曾经在PHPASP classic上开发过网站,是否需要更改某些内容。您可以更改单个/几个文件,而没有人会真正注意到。也许有人在上传过程中请求更改的文件,但这大约是半秒的余量。对于大多数较小的网站来说,这没问题。

但是最新的网站是使用C# MVC构建的,当您更改代码时,您需要重新构建网站并上传更改后的DLL文件。但是,当您更改DLL文件时,它将重新启动您的网站并重置所有活动的sessions。它还必须重新加载所有内容,而大型网站则可能需要几分钟才能加载所有内容。
浏览该网站的每个人都会注意到并需要再次登录。

主要网站更新并不常见,所以这不是问题。但是我们确实有定期的促销“小”更新。就像“填写此表格并获得三个月的免费会员资格”或“上传...的图片的前10个将获得价格”一样。我想您会随心所欲。
有些促销活动是类似的,可以使用一个模块根据显示的设置显示正确的信息,但是很多时候它需要自定义代码。

我在考虑一个系统,其中每个升级都是基于接口的自己的DLL文件,然后使用DLLType.GetTypeActivator.CreateInstance动态加载InvokeMember。尽管这可能行得通,但我想知道这是否是正确的方法。

所以我的问题是:如何在不重新加载整个网站和删除会话的情况下动态更新.NET网站(例如回收应用程序池)。

评论

为了回应您的悬赏评论:我工作的大型网站通过负载平衡器和进程外会话来处理较小的代码更改,就像处理大型代码一样,因为部署到活动中的所有代码都必须经过审查/签核过程,我们不能只是在服务器上放置代码。我猜我们对“大”的定义可能不匹配;)

#1 楼

查看“应用程序初始化” IIS 7.5,Windows 2008 R2(较难设置)IIS 8,Windows 2012应用程序初始化允许任何应用程序(应用程序池非站点)重新启动以重叠并使用旧的,仍然在预热新应用程序的同时运行先前的应用程序。一旦启动了新应用程序(由您可以设置的URL决定),它将开始使用新应用程序并关闭前一个应用程序。将应用程序初始化与方法结合使用以确保会话在整个应用程序池重新启动之间保持不变,可以使您的站点无缝地重新启动。 (Zhaph对机器密钥有很好的说明。)

除了上面的应用程序初始化配置链接之外,您还要查看触发网站重启的原因-自从网站重启不使用应用程序初始化,站点重启将是无缝的。

您可以配置IIS,以便DLL更新不会立即触发站点重启,也不会更改web.config(高httpRuntime和外部配置文件上的ChangeNotification值(与您的站点相关)。

最终结果是,您可以在不重新启动站点的情况下更新DLL /代码,然后强制重新启动将使用的应用程序AppInitialization背景会为代码的无缝更改预热。

协同执行这些操作对于无缝重启非常有效。

评论


那里有一套很好的步骤-当然要考虑一下:)

–扎夫-本·杜吉德
15年2月20日在23:33

这听起来像我要找的东西。尝试一下并进行设置。谢谢

–Hugo Delsing
2015年2月21日在6:31

@HugoDelsing希望它对您有用。

–jeffreypriebe
2015年2月22日,下午1:37

谢谢,这是我最终使用的,效果很好。

–Hugo Delsing
2015年2月27日14:11在

@HugoDelsing很高兴听到它也对您有用。

–jeffreypriebe
15年2月27日在20:45

#2 楼

有多种方法可以处理您的要求,还可以从几个方面解决您的问题:

处理促销活动的小更新

您真正要做什么在这之后是一个内容管理系统或类似的系统,它使您可以即时编辑内容(从Wordpress / Drupal或从.NET的角度来看N2 CMS,Umbraco,Orchard等),但是有些事情您可以

因为只有触摸某些类型的文件(web.config(s),/bin//app_code/文件夹的内容,ASP.NET才会真正重新加载)-并具有“其他文件更改”的可配置限制(基本上,一旦您在站点中修改了这么多文件,应用程序池就会重新启动-NumRecompilesBeforeAppRestart),您可以考虑做一些检查其他文件夹中的静态内容的操作(即.html)文件,您可以根据需要拉入并显示该文件,或者利用LoadControl方法(该方法采用了指向q43的字符串路径) 12079q用户控件并动态加载-您如何确定要显示的控件是另一个更适合StackOverflow的问题-但是我建议您使用基于命名约定的解决方案。

您还可以考虑使用类似托管扩展框架(MEF-从版本4开始是.NET框架的完整部分),它允许您编写基于插件的体系结构并在.ascx目录之外指定文件夹来监视新的.DLL,尽管我我们没有尝试过这样做是否可以避免应用程序重启的问题,我在网络环境中为向站点添加通用功能而很好地使用了它。

如果没有吸引力,那么我能想到的唯一其他选择就是像在经典ASP中一样,将控件添加为“前置代码”,即使用/bin/块而不是已编译的“隐藏代码”包含运行该控件的逻辑的类-这将消除对DLL更改的需要,但会因为在动态编译该控件而造成一些首次性能损失的代价-再次,您需要与<script runat="server">保持平衡如果您要进行很多小的更改。

如何在应用程序重新启动期间保持会话?

这可能是一个更容易解决的问题,涉及三个关键步骤:



将MachineKey(IIS7,但仍然保持8位)配置为恒定值而不是NumRecompilesBeforeAppRestart-这意味着当AppPool回收时,它将使用相同的键,因此可以在回收之前解密会话cookie,viewstate等。
设置状态服务器或配置数据库以保存会话状态。
切换在web.config的SessionState元素中使用AutoGenerateInProcStateServer

这样,您将拥有持久的会话,这些会话在应用程序重新启动后仍然有效。但是,这些并不是“免费的”-您存储在会话中的所有内容现在都必须可序列化,并且由于每次页面加载现在都需要更多的网络行程才能获得并可能释放会话数据,因此您的性能会受到轻微影响。 />
但是,如果您处于部署后需要花费“几分钟”才能重新启动应用程序的位置,则可能要考虑迁移到负载平衡的环境,或者至少要考虑到热点-可交换的暂存/实时设置(例如由Azure / AWS / etc等提供的设置)-通过这种方式,您可以在更新服务器时使服务器脱机或使用新代码进行准备,然后将其交换-采取了解决共享会话的步骤(请参见上文),这将正常工作,并且对您的用户没有影响。

评论


谢谢您的回答。不幸的是,CMS不是我想要的。我不想更改内容,我想更改代码。有关会话的部分仅是示例。更改它并不能解决重新加载DLL文件时该站点关闭一两分钟的问题。 MEF部分很有趣,但是它是我正在考虑的系统的第三方解决方案。因此+1是努力的目标,但不幸的是,这并不是我的问题的答案。

–Hugo Delsing
2015年2月20日14:37



我已经更新了答案,以解决其中的几个问题:MEF由MS发布,自v4起已成为.NET框架的完整部分。您可以尝试对新控件使用前端代码,或者采用负载平衡/分段实时设置,该设置可以使服务器启动并运行,然后将其交换。

–扎夫-本·杜吉德
15年2月20日在17:53

我已经概述了使用应用程序初始化的替代解决方案。好处是所有代码和服务器设置都是“正常”的,而无需特殊的负载平衡或动态加载控件,从而使您的运行环境更加简单。当然,出于其他原因,负载平衡/分段实时设置可能很有用。

–jeffreypriebe
2015年2月20日在23:14