【发布时间】:2011-07-02 05:29:11
【问题描述】:
我创建了一个 C# 应用程序来回收 IIS 中的所有应用程序池,一次一个,使用 Microsoft.Web.Administration.ApplicationPool 类。 ApplicationPool 上没有重新启动应用程序池的方法(如果我错了,请纠正我),所以我认为您只需要停止,然后再启动。这在大多数情况下运行良好,直到我们开始在应用程序池中获取一些陷入无限循环的线程。
默认情况下,IIS 有一个 90 秒的“关闭时间限制”,它在终止任何仍在运行的线程之前等待 90 秒,所以我会调用 ApplicationPool.Stop(),它需要 90 秒直到 IIS 终止应用程序池,在它的状态停止之前,我可以告诉它重新开始。任何试图攻击任何使用该应用程序池的应用程序的东西,都会在这 90 秒内收到 503 错误响应,直到我可以再次启动该池为止。
我决定尝试以编程方式将“关闭时间限制”更改为 5 秒,以减少出现 503 错误的应用程序数量,但 IIS 在终止应用程序池之前仍在等待 90 秒。以下是我关闭应用程序池的功能:
private void StopAppPool(ApplicationPool applicationPool)
{
ObjectState state = applicationPool.State;
TimeSpan previousShutdownTimeLimit = applicationPool.ProcessModel.ShutdownTimeLimit;
applicationPool.ProcessModel.ShutdownTimeLimit = new TimeSpan(0, 0, 5);
switch (state)
{
case ObjectState.Started:
applicationPool.Stop();
WL("Application Pool {0}'s state has gone from {1} to {2}", applicationPool.Name, state, applicationPool.State);
break;
case ObjectState.Starting:
case ObjectState.Unknown:
for (int i = 0; i < 180; i++)
{
WL("Application Pool {0}'s state is {1}. Waiting for state to become Started", applicationPool.Name, state);
Thread.Sleep(500);
state = applicationPool.State;
if (applicationPool.State == ObjectState.Started) { break; }
}
if (state == ObjectState.Started)
{
applicationPool.Start();
WL("Application Pool {0}'s state has gone from {1} to {2}", applicationPool.Name, state, applicationPool.State);
}
else
{
WL("Error starting Application Pool {0}: Application Pool never stopped", applicationPool.Name);
}
break;
case ObjectState.Stopped:
case ObjectState.Stopping:
WL("Application Pool {0} was already in a {1} state and has not been modified", applicationPool.Name, state);
break;
default:
WL("Error stopping Application Pool {0}: Unexpected ObjectState \"{1}\"", applicationPool.Name, state);
break;
}
state = applicationPool.State;
for (int i = 0; i < 180 && state != ObjectState.Stopped; i++)
{
WL("Application Pool {0}'s state is {1}. Waiting for state to become Stopped", applicationPool.Name, state);
Thread.Sleep(500);
state = applicationPool.State;
}
applicationPool.ProcessModel.ShutdownTimeLimit = previousShutdownTimeLimit;
}
为什么 ApplicationPool.ProcessModel.ShutdownTimeLimit 似乎不会影响 IIS 实际终止应用程序池所需的时间?在我尝试回收应用程序池时,是否有任何方法可以防止其他应用程序收到 503 错误?
【问题讨论】:
-
你可能不想听到这个,但你到底为什么要回收应用程序池?