IIS 7 應用程序池自動回收關閉的解決方案
如果你正在做ASP.NET,那肯定會用到IIS
如果你想在ASP.NET Application中加入某個定時任務,那想必一定是用一個線程在不停地做定時計算
那假設我們在自己的ASP.NET應用程序中加入了Quartz.NET框架,並且配置等等都OK了。
這個站點訪問量很少,現在只有幾個人上班的時候才會使用,結果第二天過來一看,后台調度的線程和計算任務都停止了,如果你抓取了Application_End事件,會發現這個事件居然被調用了。
那一定是IIS的應用程序池回收的機制在作怪了。因為IIS的默認設置里面,如果一個站點所處的應用程序池超過一段時間沒有被訪問或者請求,IIS就會自動回收這個程序池,並且把進程殺掉。那進程里面的線程肯定也活不下來了。
但是我們可以通過設置應用程序池參數使其不會被簡單的自動回收(有些情況無法避免,比如熱部署的站點,錯誤數量超限等等)
在IIS中找到這個站點所用的程序池,點擊“高級設置...”
在打開的列表中更改以下設置:
回收——固定時間間隔(分鍾) 改為 0
——虛擬/專用內存限制(KB) 改為 0
進程模型——閑置超時(分鍾) 改為 0
這樣子,一般情況下程序池就不會被自動回收了,后台一些簡單的計算線程就會正常工作
我的網站有大量用戶數據交換,需要保存很多臨時數據,所以為了使網站更快,我用到很多 Application,但是很多時候莫明其妙的Application 數據丟失了,使得網站無法再保證正確運行,在網站搜了好多久,大家說是因為應用程序池被收回了,所在我想,主動按一定時間在服務器自動回收之前用我做個程序回收,保證Application數據不丟失,請高手寫出完整asp代碼,如果問題得到很好的解決,我可以考慮付您人民幣
如果這樣asp 頁面不能實現,請給我一個很好解決Application 數據丟失的問題,Application 必須要用,用數據庫解決的話網站太慢了
首先要給WScript.Shell權限,因為這個組件太危險,所以一般情況是禁止的,如果定時執行回收進程池可以計划任務中添加指定時間激發一個IIS.vbs(回收進程)
IIS.vbs代碼如下
set WebAppPool = GetObject("IIS://LocalHost/w3svc/AppPools/DefaultAppPool")
WebAppPool.Stop
WebAppPool.Start
set WebAppPool=Nothing
網站由於使用比較多的緩存,有時會出現緩存錯誤,導致程序異常,這個時候需要回收一個應用程序池就可以了。
以前每次都是通過遠程桌面連接到服務器,然后在應用程序池上右擊》回收,感覺比較麻煩,於時找了如下的一個辦法來實現。
其實就是普通的一個asp.net頁面,加上一個按鈕,進行回收,主要程序如下:
2 protected void StartStopRecycleApp(string method)
3 {
4 string AppPoolName = this.tbAppName.Text.Trim();
5 //string method = "Recycle";
6
7 try
8 {
9 DirectoryEntry appPool = new DirectoryEntry("IIS://localhost/W3SVC/AppPools");
10 DirectoryEntry findPool = appPool.Children.Find(AppPoolName, "IIsApplicationPool");
11 findPool.Invoke(method, null);
12 appPool.CommitChanges();
13 appPool.Close();
14 lbMsg.Text = string.Format("應用程序池{0}{1}成功", AppPoolName,method);
15 }
16 catch (Exception ex)
17 {
18 lbMsg.Text = string.Format("應用程序池{0}{2}失敗:{1}", AppPoolName, ex.Message,method);
19 }
20 }
tbAppName是一個textbox,用來輸入應用程序池的名字,如“DefaultAppPool”。
當method="Recycle"時就是回收,為“Start”時是啟動,為“Stop”時是停止。
注意:
1. 必須引入System.DirectoryServices包
2. 運行此程序的應用程序也的用戶必須權限比較高,可以單獨為此程序提供應用程序程,或者建立一個虛擬目錄在配制里模擬高級用戶(如administrators或者system),否則應用程序會拋出“拒絕訪問”的異常。
應用程序池在使用一段時間后需要回收,想用程序來控制,就用vbs實現了以下代碼,在asp上一樣運行。
set apppools = GetObject("IIS://LocalHost/W3SVC/AppPools")
for each apppool in apppools
msgbox apppool.name
apppool.recycle
next
上面的程序在安裝有iis的服務器上面運行,即可彈出所有的應用程序池,想回收指定的應用程序池,只需要判斷相應的apppool.name即可。
后面是在網上(suntw.com)找到的相關操作iis的vbs腳本。
'設置應用程序池的屬性
function SetAppPoolSetting(AppPoolName,Values)
SetAppPoolSetting=false
Set apps=GetObject("IIS://localhost/w3svc/AppPools/"&AppPoolName)
SetValue=split(Values,"|")
apps.CpuLimit=int(SetValue(1))*1000'最大CPU百分比
apps.CPUAction=SetValue(2)'超過處理方式0忽略1關閉
apps.PeriodicRestartMemory=int(SetValue(3))*1024'虛擬內存
apps.PeriodicRestartPrivateMemory=int(SetValue(4))*1024'物理內存
apps.PeriodicRestartTime=SetValue(5)'回收時間
apps.SetInfo
set apps=nothing
SetAppPoolSetting=true
end function
'創建一個池並設置屬性
'================================================================
function CreateAppPool(NewAppPoolName)
Set AppPools = GetObject("IIS://localhost/W3SVC/AppPools")
set NewPool = AppPools.Create("IIsApplicationPool", NewAppPoolName)
NewPool.AppPoolIdentityType = 2'預定義賬戶0本地系統1本地服務2網絡服務
NewPool.PeriodicRestartMemory = 512 * 1000 '最大虛擬內存使用值
NewPool.PeriodicRestartPrivateMemory = 500 * 1000 '500物理內存限制'
NewPool.CPUAction = 0'超過CPU不操作,1就是超過cpu就關閉。
NewPool.CPULimit = "80000"'最大80%的CPU
NewPool.PeriodicRestartTime = 180'內存回收時間(分鍾)
NewPool.CPUResetInterval = 2'刷新CPU使用率值(分鍾)
NewPool.AppPoolAutoStart = true'自動啟動此池
NewPool.SetInfo
Set AppPools = nothing
set NewPool = nothing
if err.number=0 then CreateAppPool=true
end function
2.
IIS可以設置定時自動回收,默認回收是1740分鍾,也就是29小時。IIS自動回收相當於服務器IIS重啟,應用程序池內存清空,所有數據被清除,相當於IIS重啟,在度量快速開發平台服務器端,為了減小數據庫負擔,內存中暫存了很多信息,不適合頻繁的回收,因為回收會造成服務器端所有存在內存中的數據丟失,如果沒有及時保存到數據庫中,可能導致程序出現問題。而如果系統使用高峰時期,並不適合回收,回收可能導致幾十秒IIS無響應,對於正在工作的人員來說,是一種很不好的體驗,會以為是網絡或者掉線等問題。因此,基於以上的分析,我們需要設置IIS在指定的時間內定時回收。
度量快速開發平台(以下簡稱:度量平台)服務端搭建采用Webservice方式進行,這就需要正確的配置IIS(Internet Information Service)才能保證服務端可靠、穩定的運行,以給客戶提供更好的用戶體驗。IIS為保護服務器資源,有一個應用程序池的回收功能,並且已經默認設置1740分鍾回收一次(29小時),為了更好的設置該屬性,我們有必要對IIS回收功能設置進行掌握,並根據應用的實際情況配合調整,以達到系統運行的最佳效果。
IIS應用程序池回收,找到相應的應用程序池並點擊高級設置,就可以看到回收的相關設置(本文以windows2008R2下的IIS7為例,Windows2012類似)。
(圖1)
發生配置更改時禁止回收:如果為True,應用程序池在發生配置更改時將不會回收。
固定時間間隔(分鍾):超過設置的時間后,應用程序池回收,為0意味着應用程序池不會按固定間隔回收。系統默認設置的時間是1740(29小時)。
禁用重疊回收:如果為true,將發生應用程序池回收,以便在創建另一個工作進程之前退出現有工作進程。
請求限制:應用程序池在回收之前可以處理的最大請求數。如果值為0,則表示應用程序池可以處理的請求數沒有限制。
生成回收事件日志條目:每發生一次指定的回收事件時便產生一個事件日志條目,里面的明細設置不一一介紹。
根據度量平台服務端配置情況看,IIS默認設置的1740分鍾回收進程的策略並不合理,因為每1740分鍾回收,在過程中可能就處於用戶使用系統的高峰時段,為避免可能在高峰時段引起非可控問題,我們建議在每周六深夜(例如晚上1點,2點)進行IIS回收。
如果我們在IIS應用程序池的高級設置中,進行回收設置,那么只有兩種方式進行,一種是固定時間間隔,一種是手動回收。固定時間間隔設置,並不太好在深夜設置,以保證每周周六深夜執行回收。我們推薦采用windows “任務計划程序”配置一個操作系統定時任務執行腳本程序來實現IIS回收,設置方便,也可以靈活調整。 要通過腳本執行IIS的功能,需要在IIS安裝配置的時候,勾選上管理工具中的“IIS管理腳本和工具”(見下圖)。
用vbs腳本及批處理文件,結合任務計划程序,保證在每周六深夜1點執行IIS回收。
Recyclepool.vbs 文件內容: appPoolName = WScript.Arguments(0) Set oWebAdmin = GetObject("winmgmts:root\WebAdministration") Set oAppPool = oWebAdmin.Get("ApplicationPool.Name='" + appPoolName + "'") oAppPool.Recycle set fso=createobject("scripting.filesystemobject") if (fso.fileexists("d:\appPool\recycleIISPool.log")) then '1-forreading,2-forwriting,8-appending set file=fso.opentextfile("d:\appPool\recycleIISPool.log",8,ture) else set file=fso.createtextfile( "d:\appPool\recycleIISPool.log",8,ture) end if 'write(x)寫入x個字符,writeline寫入換行,writeblanklines(n)寫入N個空行 file.writeline now&" 應用程序池“"&appPoolName &"”已經回收成功。" file.close |
Recyclepool.bat文件內容: cscript D:\appPool\recyclepool.vbs platweb |
用vbs腳本及批處理文件,結合任務計划程序,保證在每周六深夜1點執行IIS回收。
成功用windows計划任務解決IIS定時回收問題。