[英]Automatically restarting IIS when it does not respond
這更多是一個最佳實踐問題。 我制作了一個小程序,每15分鍾運行一次c#命令行程序,它使用HttpWebRequest和HttpWebResponse檢查URL,如果它們沒有以OK狀態答復,則使用Process.Kill結束名為“ w3wp”的進程,這就是我通常會這樣做,殺死進程並讓它們重新啟動比通過IIS管理器和回收應用程序池更快。 在遷移之后,有一些舊的舊版軟件在IIS8上無法完全正常工作,有時它可以持續數月而不停頓,而其他時候則可以每周發生一次。 我真的不知道該如何解決它,而我的老板也不想讓我花時間在它上面,所以我做出了解決。
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;
我只是想知道是否有更好的方法來處理IIS的重新啟動。 手動回收應用程序池往往會起作用,所以也許比殺死進程更好的方法? 還是無論如何都重要嗎?
為了完整起見,我想提供我“編寫”的powershell代碼(大多數是通過我修改和重寫的stackoverflow獲取的示例,也許有人認可他的工作)。 這就是我現在正在做的事情。 使用任務計划程序每15分鍾運行一次。 還決定添加一個日志。
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
首先,您沒有重新啟動IIS,而是殺死了一個應用程序池進程。
IIS具有多個組件,並且可以運行許多應用程序池,因此,如果您知道問題出在該應用程序池內,那么重新啟動應用程序池而不是整個服務是一個好主意。
如您所說,與終止基礎進程相比,回收AppPool是更好的選擇。 回收時,當前正在執行的請求將完成,並且將以適當的方式關閉進程,而不僅僅是終止進程。
當使用C#查找Microsoft.Web.Administration
命名空間時,大多數IIS可以通過API訪問。 應該有關於如何回收AppPool的示例。
或者,您可以編寫一個小的PowerShell腳本,執行相同的操作。 通常,管理員更喜歡腳本而不是黑盒可執行文件。
PS我只是看了看您的代碼,實際上您正在殺死所有應用程序池,即使它們與您有問題的站點無關,這在您的服務器上可能還可以,但是在共享多個應用程序/站點的服務器上會非常糟糕。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.