发现问题
生产环境中,w3wp.exe占用cpu很高,一直在90%以上,导致网站整体性能下降,但是此现象在测试环境无法重现,怎么办?
一个办法,在生产环境中定位问题。
定位问题
对付这种情况,我用的是windbg(注:服务器是windows 2003)对线上程序进行调试。
1.安装windbg到c:\windbg
2.抓取dump,然后依次执行:开始-> 运行 -> cmd-> 敲入cscript.exe “C:\windbg\adplus.vbs” -hang -pn w3wp.exe -o d:\
3.载入sos.dll 组件,c:\windows\microsoft.net\framework\v2…下面的sos.dll 拷贝到c:\windbg下
4.加载符号: 填写SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols


5.载入dump
载入:d:\w3wp.exe__media__PID__4040__Date__05_04_2010__Time_08_26_40PM__162__Manual Dump.dmp

出现如下界面:

6输入命令:
在上图标红的地方输入命令
a.先载入.net 的sos.dll,用于解释.net符号
0:000> .load sos.dll
b. 查看运行时间:
0:000> !runaway

c.查找哪些.net 的托管线程
0:000 >~* e!clrstack
由于结果太多,这里不列了,得到运行最长时间的24号线程是托管线程,其实可以多截取几个 dump,每个线程号持续时间相减,得到最大值
d.定位到相应的线程号:
0:000 > ~24s
e: 查看 .net 调用堆栈
0:024> !clrstack
OS Thread Id: 0×10d8 (24)
ESP EIP
0221d864 7c95860c [HijackFrame: 0221d864]
0221d8b0 7aaaeefc System.Text.RegularExpressions.RegexInterpreter.Go()
0221db5c 7a5bf3a1 System.Text.RegularExpressions.RegexRunner.Scan(System.Text.RegularExpressions.Regex, System.String, Int32, Int32, Int32, Int32, Boolean)
0221db8c 7a5bf187 System.Text.RegularExpressions.Regex.Run(Boolean, Int32, System.String, Int32, Int32, Int32)
0221dbc0 7a5a9bbd System.Text.RegularExpressions.RegexReplacement.Replace(System.Text.RegularExpressions.Regex, System.String, Int32, Int32)
0221dbf8 7a59ca92 System.Text.RegularExpressions.Regex.Replace(System.String, System.String, Int32, Int32)
0221dc1c 7a59c9e7 System.Text.RegularExpressions.Regex.Replace(System.String, System.String)
0221dc2c 02850932 Test.BLL.ParseNewsDetail.GetNewsContent(System.String, System.String)
0221dcd0 1cc0f956 Test.WebSearchManage.AddNews.GetNewsDetail(System.String, Media.Common.EncodingType, System.String ByRef, System.String ByRef, System.String ByRef)
0221dd18 1cc0ecb1 Test.WebSearchManage.AddNews.InitRecordControl(System.String, Media.Common.EncodingType)
0221df48 1cc0e4c4 Test.WebSearchManage.AddNews.Page_Load(System.Object, System.EventArgs)
0221e18c 66f2a7ff System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)
0221e19c 660b2594 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)
0221e1b0 660aba84 System.Web.UI.Control.OnLoad(System.EventArgs)
0221e1c4 660abac3 System.Web.UI.Control.LoadRecursive()
0221e1dc 660a7b74 System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)
0221e334 660a77a4 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)
0221e36c 660a76d1 System.Web.UI.Page.ProcessRequest()
0221e3a4 660a7666 System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)
0221e3b0 660a7642 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)
解决问题:
问题基本找到,是Test.BLL.ParseNewsDetail.GetNewsContent(System.String, System.String)这个函数有问题。
经过JetBrains dotTrace 测试,测出这个函数里一个正则表达式效率低,随即改用了其他方式。然后布置新版本,cpu利用率降到30%。

