繁体   English   中英

在IIS7中以编程方式回收应用程序池的问题

[英]Issues Programatically Recycling Application Pools in IIS7

我创建了一个C#应用程序,使用Microsoft.Web.Administration.ApplicationPool类一次一个地回收IIS中的所有应用程序池。 ApplicationPool上没有方法可以重新启动应用程序池(如果我错了,请纠正我),所以我想你只需要停止,然后开始。 这在大多数情况下工作正常,直到我们开始在应用程序池中获得一些陷入无限循环的线程。

默认情况下,IIS有一个90秒的“关闭时间限制”,在它终止任何仍在运行的线程之前等待90秒,因此我将调用ApplicationPool.Stop(),并且在IIS终止应用程序池之前需要90秒,在它的状态将被停止之前我可以告诉它重新开始。 任何试图使用该应用程序池命中任何应用程序的内容,在我可以再次启动池之前,会在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错误?

John Koerner的回答肯定有助于我指出正确的方向。 使用Recycle会删除503错误。 诀窍是如何杀死无限循环。

以下是您必须采取的步骤,以便回收应用程序池以终止进程并遵循ApplicationPool.ProcessModel.ShutdownTimeLimit属性:

  1. 创建一个ServerManager对象
  2. 循环访问ServerManager对象上的ApplicationPools,直到找到您关心的appPool。 提示:ApplicationPools.First(p => p.Name ==“DefaultAppPool”)是一个有用的功能
  3. 更新ApplicationPool.ProcessModel.ShutdownTimeLimit
  4. 在ServerManager对象上调用CommitChanges()。 注意:您提交更改的ServerManager对象必须是您用于获取ApplicationPool对象的对象,您对其进行了更改。 你不能只做新的ServerManger()。CommitChanges();
  5. 睡一秒钟,以便在IIS中读取配置值。 此时,您应该在IIS中看到ApplicationPool上的值更改
  6. 在ApplicationPool上调用Recycle或Stop

在回收ApplicationPool时,IIS有点奇怪,因为新的w3wp.exe ApplicationPool进程将立即启动,但旧的应用程序池将等待ApplicationPool.ProcessModel.ShutdownTimeLimit中的秒数关闭。 然后它会将仍在运行的任何内容移动到新进程。 但是如果你再次回收它,它将杀死无限循环(在ShutdownTimeLimit中等待适当的时间之后)。

总而言之,正确提交更改,等待它们生效,然后执行循环,然后再次执行它,如果你有一个想要杀死的无限循环。

我已经发布了源代码,并最终可执行这里在我的博客。

要在应用程序池上重新启动,可以使用“ 回收方法”。 这可能不会缓解90秒的问题。 您可以使用回收对象中的某些内容来调整超时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM