這是這兩天剛剛發現的問題,記下來,希望對被web性能困擾的同仁有所幫助!
下面說說網站的環境和狀況吧:
環境:win2003 + asp.net + sqlserver2000, 一個在線讀書項目,日PV超500萬,獨立IP超3萬
狀況:
1)內存占用218M平穩;
2)cpu約占5%,但是每隔20秒會突然沖到30%,有時甚至50%;(這個很重要)
3)每次重新更新發布程序,cpu會穩定占5%一段時間(約30分鐘),之後就會如上面第2條(這個也很重要)
我分析了下,認為應該是有定時器這類的東西每隔20秒觸發一次,清理程序的緩存之類的東西,由於剛開始緩存並不大,所以更新程序之後前30分鐘並沒有出現cpu不穩定的問題,30分鐘後隨著緩存變大,需要清理的緩存越多,所以引起cpu不穩定。
於是我查遍了所有程序,沒有定時器之類的東西,連和20相關字也沒搜到,真是納悶了。又仔細想了想,能觸發定時器這類的東西,就只有global.asax了,看了下這個文件,只有Session_End這個事件又幾行代碼,如下
void Session_End(object sender, EventArgs e)
{
// 在會話結束時運行的代碼。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式設置為
// InProc 時,才會引發 Session_End 事件。如果會話模式設置為 StateServer
// 或 SQLServer,則不會引發該事件。
if (Session.SessionID != "")
{
Application.Remove("id" + Session.SessionID);
Application.Contents.Remove("id" + Session.SessionID);
}
}
難道真是這裡的問題,嘗試把這段代碼去掉,更新發布,cpu居然一直保持平穩了。
看來終於找到問題所在了,為了進一步了解這裡到底有多少操作,我把代碼改成了這樣
void Session_End(object sender, EventArgs e)
{
// 在會話結束時運行的代碼。
// 注意: 只有在 Web.config 文件中的 sessionstate 模式設置為
// InProc 時,才會引發 Session_End 事件。如果會話模式設置為 StateServer
// 或 SQLServer,則不會引發該事件。
if (Session.SessionID != "")
{
string sessoinId = Session.SessionID;
string applicationContent = Application.Contents["id" + Session.SessionID].ToString();
SessionLog.Insert(sessionId,applicationContent,DateTime.Now); // 這裡把數據記錄到數據庫中
Application.Remove("id" + Session.SessionID);
Application.Contents.Remove("id" + Session.SessionID);
}
}
更新發布,約半個小時之後,數據庫裡終於有了數據,發現時間竟然都是 00-01 秒之間,20-21秒之間,40-41秒之間,每段時間約有70-120條數據。
我不是.net專家,不知道這個Session_End到底是怎麼樣觸發的,不過通過測試結果我個人認為Session_End應該是每隔20秒觸發一次,發現有過期的Session就執行Session_End裡面的代碼,比如我的網站就進行了100多次的Application.Remove(),所以每隔20秒中cpu就會跳一次。
有誰能給我詳細解釋下嗎,如果有那太感謝了。
也希望這個對被性能困擾的各位有點幫助。