2016-08-09 19 views
1

これはベストプラクティスの問題です。私はHttpWebRequestとHttpWebResponseを使ってURLをチェックする毎回実行する小さなC#コマンドラインプログラムを作りました。もしOKステータスで答えなければ、Process.Killを使って "w3wp"という名前のプロセスを終了します。私は通常どおり、プロセスを強制終了し、IISマネージャーを経由してアプリケーションプールをリサイクルするよりも再起動させる方が速いです。私たちが移行した後にIIS8でかなり問題なく動作していない古いソフトウェアがあります。時にはそれが失速することなく数ヶ月かかることもあり、毎週起こることもあります。私の上司は私にそれに時間を費やすことを望ましくないので、このkludge /回避策を作りました。IISが応答しなくなったときに自動的にIISを再起動する

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の再起動を処理する方法があるかどうかは疑問です。手動でアプリケーションプールをリサイクルすると機能する傾向があります。おそらく、プロセスを強制終了するよりも優れた方法でしょうか?とにかくこれがうまくいくかどうかはそれほど重要ですか?

答えて

0

まず、IISを再起動せずに、1つのアプリケーションプールプロセスを強制終了します。

IISにはいくつかのコンポーネントがあり、多くのアプリケーションプールを実行できるため、問題がそのアプリケーションプール内にあることがわかっている場合は、サービス全体ではなくアプリケーションプールを再起動することをお勧めします。

あなたが言ったように、AppPoolをリサイクルする方が、基本プロセスを強制終了するよりも優れています。リサイクルすると、現在実行中のリクエストは終了し、プロセスは単に殺されるのではなく適切な方法でシャットダウンされます。

ほとんどのIISは、C#を使用してMicrosoft.Web.Administration名前空間を調べると、APIを介してアクセスできます。 AppPoolをリサイクルする方法の例があります。

また、同じことを行う小さなPowerShellスクリプトを記述することもできます。通常、管理者は実行可能なブラックボックスではなくスクリプトを使用します。

P.S.私はちょうどあなたのコードを見て、あなたは問題のあるサイトとは関係がなくても、実際にはすべてのアプリケーションプールを殺していますが、それはサーバー上では問題ないかもしれませんが、複数のアプリケーション/サイトを共有するサーバーでは非常に悪いです。

+0

Powershellは面白いと聞こえますが、私が経験したことは何もありません。基本的にはC#だけです。 – Dennis

+0

Powershellは私が思ったよりも簡単に見えますが、オンラインで見つかったサンプルコードを使って同様のプログラムを作成しました。代わりにアプリケーションプールが再起動されます。 – Dennis

0

完全性のために、私が書き込んだ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 = "[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