简体   繁体   English

不响应时自动重新启动IIS

[英]Automatically restarting IIS when it does not respond

This is more of a best practices question. 这更多是一个最佳实践问题。 I've made a little c# command line program that I run every 15 minutes which checks an URL using HttpWebRequest and HttpWebResponse, if they do not answer with OK status I use Process.Kill to end the processes named "w3wp", this is what I would do normally, it's faster to just kill the processes and let them restart than go via the IIS manager and recycle the application pool. 我制作了一个小程序,每15分钟运行一次c#命令行程序,它使用HttpWebRequest和HttpWebResponse检查URL,如果它们没有以OK状态答复,则使用Process.Kill结束名为“ w3wp”的进程,这就是我通常会这样做,杀死进程并让它们重新启动比通过IIS管理器和回收应用程序池更快。 There's some old legacy software which isn't working quite problem free with IIS8 after we migrated, sometimes it can go months without stalling, other times it can happen weekly. 在迁移之后,有一些旧的旧版软件在IIS8上无法完全正常工作,有时它可以持续数月而不停顿,而其他时候则可以每周发生一次。 Don't really know how to troubleshoot it and my boss don't want me to spend time on it either, so I made this kludge / workaround. 我真的不知道该如何解决它,而我的老板也不想让我花时间在它上面,所以我做出了解决。

case "alive":

                        Console.WriteLine("Check if website(s) respond:");
                        bool restartIIS = false;
                        List<string> checkURL;
                        checkURL = new List<string>();
                        checkURL.Add("http://www.test.se");
                        checkURL.Add("http://www.test.fi");
                        checkURL.Add("http://www.test.com");

                        foreach (string value in checkURL)
                        {                            
                            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(value);
                            HttpWebResponse response = (HttpWebResponse)req.GetResponse();
                            if (response.StatusDescription.Equals("OK"))
                            {
                                Console.WriteLine("Website (" + value +") is up");
                            }
                            else
                            {
                                Console.WriteLine("Website is down, restarting IIS");
                                restartIIS = true;
                            }
                            response.Close();


                            if (restartIIS == true)
                            {
                                foreach (var process in Process.GetProcessesByName("w3wp"))
                                {
                                    process.Kill();
                                }
                                sendDowntimeAlert();
                                //function that sends me an email notifcation
                            }
                    }
                    break;

I'm just wondering if there are better ways to handle rebooting of IIS. 我只是想知道是否有更好的方法来处理IIS的重新启动。 recycling the application pools manually tends to work so perhaps that would be a better approach than killing processes? 手动回收应用程序池往往会起作用,所以也许比杀死进程更好的方法? Or does it matter that much if this works anyway? 还是无论如何都重要吗?

I wanted to provide the powershell code I "wrote" (mostly acquired samples via stackoverflow that I've modified and rewritten, perhaps someone recognizes his work) for sake of completeness. 为了完整起见,我想提供我“编写”的powershell代码(大多数是通过我修改和重写的stackoverflow获取的示例,也许有人认可他的工作)。 This is how I am doing it instead now. 这就是我现在正在做的事情。 Using Task Scheduler to run it every 15min. 使用任务计划程序每15分钟运行一次。 Also decided to add a log. 还决定添加一个日志。

param([string]$emailNotify, [string]$checkUrl)

$CurrentDate = [DateTime]::UtcNow.ToString('u')
$Logfile = "C:\scheduled-tasks\powershell\IISkeepalive.log"
Function LogWrite
{
   Param ([string]$logstring)

   Add-content $Logfile -value $logstring
}

Function Mailer($emailTo, $checkUrl) 
{ 
$message = "Website: (" + $checkUrl + ") appears to be down" 
$emailFrom = "info@recipient.com" 
$subject="website may be down" 
$smtpserver="smtp.server.com" 
$smtp=new-object Net.Mail.SmtpClient($smtpServer) 
$smtp.Send($emailFrom, $emailTo, $subject, $message) 
} 

Function testWebsite($emailTo, $checkUrl)
{
# First we create the request.
$HTTP_Request = [System.Net.WebRequest]::Create($checkUrl)

# We then get a response from the site.
$HTTP_Response = $HTTP_Request.GetResponse()

# We then get the HTTP code as an integer.
$HTTP_Status = [int]$HTTP_Response.StatusCode

If ($HTTP_Status -eq 200) { 
    LogWrite ("<" + $CurrentDate + "> Site (" + $checkUrl + ") is OK")
}
Else {
    LogWrite ("<" + $CurrentDate + "> The site (" + $checkUrl + ") may be down, please check!")
    Mailer $emailTo $checkUrl
    Start-Sleep -s 1

    Invoke-Command -ComputerName "SERVER" -ScriptBlock { Restart-WebAppPool "PoolName1" }
    Start-Sleep -s 1
    Invoke-Command -ComputerName "SERVER" -ScriptBlock { Restart-WebAppPool "PoolName2" }
    LogWrite ("<" + $CurrentDate + "> Application pools recycled")
}

# Finally, we clean up the http request by closing it.
$HTTP_Response.Close()
}

testWebsite $emailNotify $checkUrl

First of all, you are not rebooting IIS, you are killing one Application Pool process. 首先,您没有重新启动IIS,而是杀死了一个应用程序池进程。

IIS has several components and can have many application pools running, so re-starting the application pool rather than the whole service is a good idea if you know the problem is within that application pool. IIS具有多个组件,并且可以运行许多应用程序池,因此,如果您知道问题出在该应用程序池内,那么重新启动应用程序池而不是整个服务是一个好主意。

As you said, recycling the AppPool is the better choice compared to killing the underlying process. 如您所说,与终止基础进程相比,回收AppPool是更好的选择。 When you recycle, the currently executing requests are finished and the process is shut down in a proper manner rather than just killed. 回收时,当前正在执行的请求将完成,并且将以适当的方式关闭进程,而不仅仅是终止进程。

Most of IIS is accessible through an API, when using C# looking into the Microsoft.Web.Administration namespace. 当使用C#查找Microsoft.Web.Administration命名空间时,大多数IIS可以通过API访问。 There should be examples out there on how to recycle an AppPool. 应该有关于如何回收AppPool的示例。

Alternatively you can write a small PowerShell script, that does the same thing. 或者,您可以编写一个小的PowerShell脚本,执行相同的操作。 Usually administrators prefer scripts rather than a black-box executable. 通常,管理员更喜欢脚本而不是黑盒可执行文件。

PS I just looked at your code, and you are actually killing all application pools, even if they have nothing to do with your problematic site, that may be okay on your server but would be very bad on a server sharing multiple applications/sites. PS我只是看了看您的代码,实际上您正在杀死所有应用程序池,即使它们与您有问题的站点无关,这在您的服务器上可能还可以,但是在共享多个应用程序/站点的服务器上会非常糟糕。

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

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