我应该怎么做才能确保 IIS 不会回收我的应用程序?

我应该怎么做才能确保 IIS 不会回收我的应用程序?

我有一个托管在 IIS 中的 WCF 服务应用程序。在启动时,它会获取非常昂贵的(就时间和 CPU 而言)资源以用作本地缓存。

不幸的是,IIS 似乎会定期回收该进程。因此,我尝试更改应用程序池上的设置,以确保 IIS 不会回收该应用程序。到目前为止,我已更改了以下内容:

  • 将 CPU 下的间隔限制从 5 更改为 0。
  • 进程模型下的空闲超时从 20 更改为 0。
  • 回收期间的常规时间间隔为 1740 至 0。

这些够吗?我对所更改的项目有具体疑问:

  1. CPU 下的 Limit Interval 设置具体是什么意思?是不是意味着如果超过一定的 CPU 使用率,应用程序池就会被回收?
  2. “回收”到底是什么意思?应用程序是否被彻底拆除并重新启动?
  3. “工作进程关闭”和“应用程序池回收”有什么区别?进程模型下的空闲超时文档讨论了关闭工作进程。而回收下的常规时间间隔文档讨论了应用程序池回收。我不太明白这两者的区别。我以为 w3wp.exe 是运行应用程序池的工作进程。有人能解释一下这两者对应用程序的区别吗?

之所以有 IIS7 和 IIS7.5 标签是因为应用程序将在两个版本中运行,并且希望两个版本之间的答案相同。

参考图:在此处输入图片描述

答案1

回收利用

回收通常是指* IIS 启动一个新进程作为应用程序的容器,然后让旧进程ShutdownTimeLimit在被终止之前自行消失。

*- 通常:参见DisallowOverlappingRotation/“禁用重叠回收”设置

这是破坏性的,因为原始进程及其所有状态信息都被丢弃了。使用进程外会话状态(例如,状态服务器或数据库,或者如果您的状态很小,甚至可以是 cookie)可以让您解决这个问题。

但默认情况下重叠- 意味着中断持续时间被最小化,因为新进程启动并连接到请求队列,在旧进程被告知“您有 [ ShutdownTimeLimit] 秒的时间离开。请遵守。”

设置

回答您的问题:该页面上的所有设置都以某种方式控制回收。“关闭”可能被描述为“主动回收” - 进程本身决定何时退出,并以有序的方式退出。

反应性回收是指 WAS 检测到问题并终止该过程(在建立合适的替代 W3WP 之后)。

现在,这里有一些可能导致某种形式回收的东西:

  • ISAPI 认为其不健康
  • 任何模块崩溃
  • 空闲超时
  • CPU 限制
  • 调整应用程序池属性
    • 作为你的妈妈可能有一次大喊:“停止采摘否则情况永远不会好转!”
  • “ping”失败 * 实际上不是 ping 本身,因为它使用命名管道 - 更多的是“生命检测”
  • 上面截图中的所有设置

该怎么办:

一般来说:

  • 禁用空闲超时。20 分钟不活动 = 砰!旧流程消失了!下一个传入请求时将启动新流程。将其设置为零。

  • 禁用规则的时间间隔- 各方将 29 小时违约描述为“疯狂”、“恼人”和“聪明”。实际上,只有两个说法是正确的。

  • 可选打开禁止在配置更改时旋转(多于,禁用配置更改的回收) 如果您实在无法停止使用它 - 这允许您更改任何应用程序池设置,而无需立即向工作进程发出需要终止的信号。您需要手动回收应用程序池才能使设置生效,这允许您预设设置,然后使用更改窗口通过回收过程应用它们。

  • 作为一般原则,离开正在 ping已启用。这是您的安全网。我见过有人关闭它,然后网站有时会无限期挂起,导致恐慌……因此,如果设置对于您响应速度非常非常慢的应用程序来说太过激进,请稍微降低它们,看看您得到什么,而不是关闭它。(除非您通过自己的监控过程为挂起的 W3WP 设置了自动崩溃模式转储)

这足以让一个行为良好的进程永远存活下去。如果它死了,当然,它会被替换。如果它挂起,ping 应该会发现它,一个新的进程应该在 2 分钟内启动(默认情况下;最坏情况计算应该是:最多ping 频率+ping 超时+启动时间限制请求才会重新开始起作用)。

CPU 限制不是通常情况下有趣的是,默认情况下它是关闭的,而且配置为不执行任何操作;如果它配置为终止进程,那当然会触发回收。请将其关闭。请注意,对于 IIS 8.x,CPU 节流也成为一个选项。

(IIS) AppPool 不是 (.Net) AppDomain(但可能包含一个/一些)

但是...然后我们进入.Net领域,App领域回收,这也可能导致状态丢失。(见:https://blogs.msdn.microsoft.com/tess/2006/08/02/asp-net-case-study-lost-session-variables-and-appdomain-recycles/

简而言之,您可以通过触摸内容文件夹中的 web.config 文件来实现此目的 (再次进行采摘!),或者在该文件夹中创建一个文件夹,或者一个 ASPX 文件,或者其他东西……这就是关于和应用程序池回收一样具有破坏性,本机代码启动成本(它纯粹是一个托管代码(.Net)概念,因此这里只发生托管代码初始化的事情)。

防病毒软件在扫描 web.config 文件时也会触发此问题,从而导致更改通知,导致……

答案2

好心检查,

为什么要回收应用程序池?

如果你在网上查找应用程序池配置为定期自动回收的原因,你很难找到一个与内存问题无关的合理答案。社区似乎普遍接受了这样一个事实:我们的网络应用程序(或托管在 IIS 中的服务层)将需要回收以避免内存问题。

我一直认为如果你的代码需要定期重启才能正常工作,那么显然有问题。有一个错误在您的代码中的某个地方,您需要修复它,而不是偶尔重新启动该过程以使问题“消失”。

确实需要开始更多地关注内存管理在.NET 中并确保我们的应用程序可以持续运行且没有问题。

答案3

根据 OP 场景(启动/预热时初始化时间较长),需要检查的另一件事是启动时间限制(秒),默认值为 90 秒。如果初始化时间超过启动时间限制,则可以终止工作进程。

答案4

答案是,你防止 AppPool 被回收,但是你不应该。

原因是,如果发生内存泄漏,它最终将耗尽服务器的所有内存,并且 Windows 将出现蓝屏或抛出内存不足异常,从而导致同一 IIS 服务器上的其他站点瘫痪。

因此,确定该站点允许使用多少内存,并在达到该限制时设置上述设置以回收。

通常情况下,回收过程会很优雅地完成,因此最终用户不会察觉到。但是如果您使用的是 Blazor Server,则所有会话都会在服务器上运行,并且所有状态都将丢失。实际上,我看到 Blazor App 在回收过程中显示“正在连接...”消息约 5 秒钟。换句话说,对于服务器端 Blazor 应用来说,这并不优雅。

这个故事的寓意就是前面提到的,确保你的网站不会泄漏内存。在开发过程的早期测试你的内存,不要等到上线后再测试,因为 Blazor Server 占用大量内存,我的经验是我不得不花费大量时间来调试内存问题。这不是 Blazor 的错,只是 Blazor Server 应用程序的本质要求非常严格的代码。在 .net 的早期,我从不担心内存,因为 GC 会处理所有这些,但在 IIS 中运行则是另一回事。

相关内容