IIS 应用程序池每过一段时间,就异常关闭并提示:w3wp.exe [7668] 中发生了未经处理的 win32 异常。

〇、前言

在博主某次更新代码版本后,一直会隔一段时间就会出现如下提示,而且一天好几次。

出现报错的同时,应用程序池也时常自动关闭,影响了业务的正常运作,期间改了一些配置后仍然无效。

部分配置如下图:

一、原因分析

关于“Visual Studio 实时调试器”的报错,一般情况下是代码中的问题,影响到了程序的正常运行。

那么就需要进一步查找是哪个应用程序出的问题,这时需要通过“事件查看器”来查找系统日志。

打开方式:服务器管理器-->工具-->事件查看器。

筛选错误日志:

其中,同意报错的事件 ID 是相同的,点击对应的错误记录,查看具体报错内容。

这就对应上了,还是应用程序池“Timing.Interface.Operation”中的代码出了问题。

然后就是通过事件 ID 去查看最早的一条报错日志的时间,然后去查这个时间点更新了哪些内容,排查代码中的异常。

二、会导致应用程序池异常停止的情况

2.1 多线程操作耗时操作,造成拥堵逐渐加剧,内存占用到达临界值,最终导致系统崩溃

例如,一个耗时操作的接口,需要客户端调用,来更新数据。当业务繁忙时,会有很多调用请求进入,这样就会造成拥堵。

此时,可以通过锁机制,在上一个操作未完成时,不开始下一个操作,保证同一时间点仅有一个线程在更新数据。

采用两个方法:public static void Enter(object obj, ref bool lockTaken);public static void Exit(object obj);

示例代码,仅供参考:

[ApiController]
[Route("api/[controller]/[action]")]
public class AsyncInvDetailController : ControllerBase
{
	public static object obj = new object();
	private static bool acquiredLock = false;

	[HttpGet]
	public void ActralOperation()
	{
		try
		{
			if (!acquiredLock)
			{
				try
				{
					Monitor.Enter(obj, ref acquiredLock);
					Thread.Sleep(20000); // 模拟耗时操作
				}
				catch (Exception ex)
				{
					// 。。。。
				}
				finally
				{
					Monitor.Exit(obj);
					acquiredLock = false;
				}
			}
		}
		catch (Exception ex)
		{
			// 。。。。
		}
	}
}

2.2 应用程序池标识不合适

应用程序池在新建时,标识默认为 ApplicationPoolIdentity,级别也是最低的,这样可能限制了程序的运行,此时就需要确认程序的功能,是否跟所选择的标识级别对应。

如下详细介绍了四种标识的差异,供参考。

在 IIS(Internet Information Services)中,应用程序池标识决定了运行应用程序池的用户账户。不同的标识类型赋予了应用程序池不同的权限和安全级别。

标识类型 权限等级 适用场景 安全性 管理复杂度
LocalSystem 最高 需要全面控制本地系统的应用 较低 简单
LocalService 不需要网络访问的普通应用 较高 简单
NetworkService 中等 需要访问网络资源的应用 中等 简单
ApplicationPoolIdentity 自定义 多租户环境或标准 Web 应用 中等

以下是四种标识的简介:

  • LocalSystem

特点:拥有对本地计算机的完全控制权,可以访问几乎所有系统资源。

应用场景:

  • 系统管理工具:例如某些系统管理工具或服务,可能需要读取和修改系统配置文件、安装驱动程序或执行其他高级系统任务。这些操作通常需要高权限,因此 LocalSystem 是合适的选择。
  • 硬件控制:一些应用程序可能需要直接与硬件设备交互(如监控硬件状态、控制外围设备等)。这类应用通常需要较高的系统权限来完成其功能。
  • 遗留应用:例如一些老旧的应用程序,可能没有考虑到权限隔离的问题,依赖于高权限账户才能正常运行。由于设计上的限制,这些应用可能无法使用较低权限的账户。
  • 开发调试:例如开发者可能希望绕过复杂的权限设置,以便专注于功能开发和调试,而不必担心权限问题。在开发环境中临时使用 LocalSystem 可以简化权限管理和快速测试。
  • LocalService

特点:提供有限的本地权限,适合大多数不需要网络访问的应用程序。

应用场景:

  • 普通 Web 应用:例如一个简单的静态网站或不需要访问外部资源的动态网站。这类应用不需要高权限,使用 LocalService 可以提高安全性。
  • 内部服务:一些只在本地运行的服务,例如日志记录服务或监控服务。这些服务通常只需要读写本地文件,不需要网络访问权限。
  • 轻量级后台任务:定时任务或批处理作业,用于生成报告或清理临时文件。这类任务通常只需要基本的文件系统访问权限,不需要额外的网络权限。
  • NetworkService

特点:可以访问网络资源,并通过计算机的凭据进行身份验证,适合需要网络访问的应用程序。

应用场景:

  • 企业内部应用:企业内部的 Web 应用,需要访问数据库服务器或其他网络资源。这类应用通常需要访问网络资源,但不需要极高的权限,NetworkService 提供了合适的权限级别。
  • 分布式应用:多个服务器之间的协同工作,如微服务架构中的各个服务。这类应用需要跨服务器通信,NetworkService 可以满足这种需求。
  • 数据同步服务:用于定期同步数据的应用程序,可能需要从远程服务器获取数据。这类服务通常需要访问网络资源,但不需要完全的系统控制权限。
  • ApplicationPoolIdentity

特点:专门为每个应用程序池创建的虚拟账户,具有最低必要的权限,默认情况下仅限于访问应用程序池所需的资源。

应用场景:

  • 标准 Web 应用:一个典型的 ASP.NET 或 PHP Web 应用,需要访问本地文件系统和数据库。这类应用通常不需要高权限,使用 ApplicationPoolIdentity 可以最小化攻击面并提高安全性。
  • 多租户环境:在一个共享主机环境中,多个不同客户的 Web 应用托管在同一台服务器上。每个应用程序池使用独立的 ApplicationPoolIdentity 账户,可以有效隔离各个应用,防止跨站点脚本攻击(XSS)或其他安全漏洞
  • 资源受限应用:一些资源密集型应用,如视频转码服务或大数据处理服务。通过为每个应用分配独立的 ApplicationPoolIdentity,可以更好地控制资源使用和权限分配。
  • 自动化部署:CI/CD 流水线中的自动化部署步骤,涉及代码拉取、构建和发布。每个阶段的任务可以使用独立的 ApplicationPoolIdentity 来确保权限隔离和安全性。

选用和是的标志类型,应按照如下原则:

最小权限原则:始终遵循最小权限原则,只为应用程序分配所需的最低权限。
评估替代方案:在决定使用更高权限的账户之前,评估是否有其他较低权限的账户可以满足需求。
定期审查:定期检查应用程序池的标识设置,确保它们仍然符合当前的安全策略和业务需求。
使用托管服务账户:对于需要跨多个服务器的应用程序,考虑使用托管服务账户(如 gMSA),以便简化管理和提高安全性。
安全加固:即使选择了较高权限的账户,也应采取额外的安全措施,如启用应用程序池隔离、限制文件系统访问等。

2.3 应用程序池配置问题

检查应用程序池的‘高级设置’。

参考:https://www.cnblogs.com/sky6699/p/15406384.html#top

例如以下几项常用的修改项:

队列长度:HTTP.sys 将针对应用程序池排队的最大请求数。如果队列已满,新请求将收到 503“服务不可用”的响应。默认队列长度设置是1000,范围在10-65535 之间。

如果针对 64 位操作系统上的应用程序池将该属性设为 True,则为应用程序池提供服务的工作进程将处于 WOW64 (Windows on Windows64)模式。WOW64 模式下的进程是仅加载 32 位应用程序的 32 位进程。

应用程序池回收(Application Pool Recycling)是指自动重启或重新加载应用程序池的过程。这个过程涉及终止当前运行的应用程序池进程,并启动一个新的进程来接管请求。应用程序池回收的主要目的是提高应用程序的稳定性和性能,通过定期重启应用程序池来释放资源和清理内存。

特定时间:可以配置多个时间点,来定时回收。

虚拟内存限制(KB):工作进程可以使用的最大虚拟内存量(以 KB 为单位),超过此内存量,将导致应用程序池回收。如果值为 0,则表示没有限制。

专用内存限制(KB):工作进程可以使用的最大专用内存量(以 KB 为单位),超出此内存量,将导致应用程序池回收。如果值为 0,则表示没有限制。

标识,上一节已经详解过了,略过。

启动时间限制(秒):为工作进程指定的、启动并进行初始化的时间段(以秒为单位)。如果工作进程初始化时间超过启动时间限制,将被终止。

2.4 其他原因

  • 文件夹权限问题

编辑文件夹的权限:

  • 版本兼容性问题

当操作系统、.NET Framework 版本更新后,如果应用程序没有相应的调整,可能会遇到兼容性问题,从而导致异常。

  • 第三方组件或模块的问题

使用了有问题的第三方 DLL、控件或其他库,这些组件可能会引入 bug 或者与 IIS 环境不兼容,导致应用程序池崩溃。

  • 硬件故障

当以上问题都排查过后,最后还有可能黑丝硬件问题,例如硬盘故障、内存故障等等。

posted @ 2025-04-28 19:23  橙子家  阅读(745)  评论(0)    收藏  举报