症状:Azure上的ASP.NET Web Forms网站偶尔崩溃,并且所有.aspx页面请求均因此错误而失败。该问题似乎是随机的,并且只会在很长时间内发生一次。该站点可以运行几个月,没有任何问题,然后出乎意料的是,它将停止为任何.aspx页提供服务,并在每个.aspx页请求中给出错误。重新启动网站是唯一的解决方案(或重新部署,这会导致相同的情况)。
这是一个很难调试的问题,因为它是零星的,我发现的其他答案都无济于事,他们没有解决该站点将长时间部署和运行然后崩溃的问题,似乎是随机出现的。最后,我从微软那里得到了一些帮助。
Eri*_*man 17
根据Microsoft的说法,这是由Web服务器辅助进程中的内存压力触发的.Net Framework 4.7.x版本的已知错误引起的。它已在.Net Framework 4.8中修复(目前尚未发布)。我的解决方案只是检查“允许预编译的站点是可更新的”并检查“不合并”选项。
该问题的根本原因与工作进程(w3wp.exe)地址空间上的内存压力有关。在ASP.net中,当.Net Framework检测到我们已超过某个内存压力阈值时,它将继续尝试从内部缓存结构中弹出项目以释放空间。经过这样的缓存修剪,属于您的应用程序的程序集将从内存缓存中删除。这将触发一个回调委托,该委托将尝试将内存缓存中的更改反映到磁盘上程序集的缓存中,并将尝试删除从内存中缓存中弹出的.dll程序集。但是,辅助进程仍保留对此文件的引用(打开的句柄),因此删除失败。发生这种情况时,.Net Framework将在程序集旁边创建一个.delete文件,以将其标记为过期。
所有这些缓存处理的原因是不正确的插入了由具有不可更新UI的预编译过程发出的动态程序集的ASP.net内存缓存。在此编译过程中,无法更改动态程序集的名称,因为如果对ASP.net Runtime进行了更改,则指示ASP.net Runtime的编译资源所在的二进制文件中的.compiled资源文件不会更改。网站–与使用可更新UI进行的预编译相反,在该版本中,页面的标记可能会发生更改,这会更改.compiled文件,然后更改动态程序集的名称,从而防止重新使用旧名字。
对于来自具有不可更新UI的ASP.net应用程序预编译的程序集,标准是使用特殊属性将其插入工作进程中的ASP.net内存缓存中,该特殊属性将指示缓存管理器这些条目无法删除。.Net Framework 4.7.x版本中缺少此属性,并且是导致错误的原因。没有它,修剪缓存时,可以删除程序集,并且由于它们仍在使用中,因此无法从Temporary ASP.net Files文件夹(卷影副本文件夹)中删除它们。因此,这将导致创建.delete文件。在4.7之前的.Net Framework版本中,这不是问题。产品组还确认,他们将在即将发布的.Net Framework 4.8版本中解决此问题。
关于此问题,有两种解决方案:
缓存错误仅出现在4.7及更高版本的.Net Framework的内部版本中,因此,还原到4.6.x版本将使您可以继续工作而不会遇到问题。它们可以保留在4.6.x发行版中,直到今年晚些时候发布.Net Framework 4.8。截至目前,我还没有该产品系列的时间表。
当我们看到工作进程内部的内存压力过大时,将在ASP.net中修剪缓存。此内存压力的评估如下:如果您在IIS的应用程序的应用程序池中没有设置回收条件,则ASP.net将认为该阈值是计算机可用总RAM的60%。当辅助进程的专用字节超过此阈值时,内部缓存将被修剪,并且程序集将被弹出,从而导致.delete文件的外观。我建议您与客户合作,尽可能增加受影响最大的服务器可用的RAM内存,并根据托管受影响应用程序的应用程序池上的专用字节设置内存回收。
要在应用程序池上设置专用字节回收:
您可以尝试安装.Net Framework 4.8的预览版本,该版本现在可以在线下载。但是,这是预览版,您可能会遇到其他问题,直到发布框架后,该问题才得到支持。您还可以选择安装Microsoft的专用修补程序(如果需要此Nand,我会要求我提供此修补程序),该修补程序将更改.Net Framework 4.7.x中发生故障的程序集,以允许将程序集正确插入到缓存中。但是,此私有修补程序未签名,因此将要求我们在服务器上禁用组装符号检查,这可能使客户面临其他安全风险。
该错误仅影响不可更新的预编译二进制文件,因此可以避免该错误,但是启动时间显然受到很大影响。对我来说,此解决方案很简单,并且在4.8版Azure Web服务推出之前可以正常使用。
| 归档时间: |
|
| 查看次数: |
991 次 |
| 最近记录: |