Reputation: 393
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. 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. 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. 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?
Upvotes: 1
Views: 5409
Reputation: 393
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. This is how I am doing it instead now. Using Task Scheduler to run it every 15min. 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 = "[email protected]"
$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
Upvotes: 2
Reputation: 11222
First of all, you are not rebooting IIS, you are killing one Application Pool process.
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.
As you said, recycling the AppPool is the better choice compared to killing the underlying process. 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. There should be examples out there on how to recycle an AppPool.
Alternatively you can write a small PowerShell script, that does the same thing. Usually administrators prefer scripts rather than a black-box executable.
P.S. 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.
Upvotes: 0