这是这两天刚刚发现的问题,记下来,希望对被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这个事件又几行代码,如下
Code
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居然一直保持平稳了。
看来终于找到问题所在了,为了进一步了解这里到底有多少操作,我把代码改成了这样
Code
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就会跳一次。
有谁能给我详细解释下吗,如果有那太感谢了。
也希望这个对被性能困扰的各位有点帮助。