相信很多web管理员都碰到过IIS-503的错误,Service Unavailable,出现这个问题一般都是和相应站点的应用程序池有关,一般都是连接数过多导致该应用程序池占用的CPU过大而导致池假死。解决方法就是回收应用程序池。可是挂在公网上的web服务器都是对外提供24小时的服务,身为网管的你总不可能时时刻刻守在那。相信大家都有半夜被老板叫醒的经历。

 

言归正传,以下就是本人想出来一个比较懒的方法。

需要用到的工具有curl for win32,grep for win32,这些都是linux下的工具,借来用用。

以上工具请自行在百度中谷歌一下就可以得到。

思路:利用curl去获取一个页面的http头,通过这个头我们就可以判断应用程序池是否假死,如果获取到HTTP/1.1 200 OK说明应用程序池正常,如果是503或者其他就说明有问题。再通过grep去筛选关键字的行,如果这行不是返回"HTTP/1.1 200 OK"的结果就回收应用程序池。

第一,做一个healthcheck.aspx的页面,放到网站的目录下,内容随便写点,就xxx.com is ok now吧。

第二,复制以下代码,保存为AppPoolRecycle.vbs,一段回收应用程序池的代码。
strComputer = "."
Set objWMIService = GetObject _
    ("winmgmts:{authenticationLevel=pktPrivacy}\\" _
        & strComputer & "\root\microsoftiisv2")

'回收名为test的应用程序池
Set colItems = objWMIService.ExecQuery _
    ("Select * From IIsApplicationPool Where Name = " & _
        "'W3SVC/AppPools/test")

For Each objItem in colItems
    objItem.Recycle
Next

第三,判断应用程序池是否假死,如果是,运行上面的回收代码。复制以下代码为appdeadchk.vbs。

Set objShell = CreateObject("Wscript.Shell")
'利用curl获取目标网页的http头信息
strcmd1 = "%comspec% /c C:\GnuWin32\bin\curl -I
http://yangye.blog.51cto.com/healthcheck.aspx -o c:\curl.txt"
'利用grep筛选出curl获取的关键行HTTP/1.1
strcmd2 = "%comspec% /c C:\GnuWin32\bin\grep.exe HTTP/1.1 c:\curl.txt >c:\grep.txt"
objShell.Run(strcmd1)
'等待500毫秒让strcmd1的文件写完,因为strcmd2需要这个文件
WScript.Sleep 500
objShell.Run(strcmd2)

'打开经过筛选后的grep.txt文本
Const ForReading=1
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.OpenTextFile("c:\grep.txt", ForReading)
strLine = objTextFile.ReadLine
'去掉头尾的空格
strnewline = Trim(strLine)
'判断行是否等于HTTP/1.1 200 OK,如果不等于则运行c:\AppPoolRecycle.vbs
If not strnewline = "HTTP/1.1 200 OK" then
objShell.Run("c:\AppPoolRecycle.vbs")
End if

最后,利用计划任务让appdeadchk.vbs程序每5分钟运行一次。

注意:不要傻乎乎的抄袭代码,某些内容还是要自行修改的。另外如果是多站点,采用主机头方式部署的还需要在hosts文件中添加域名到IP的映射关系,建议使用内网解析,切勿绕到公网去解析。