記一個由MemCached引發的性能問題


最近有個項目用loadrunner做了壓力測試,發現並發量還不到200服務器就支撐不住了。boss那邊緊急開會,說此項目最近3個月內將有100家中大型公司用於校園招聘工作,如果這個問題不解決公司有可能玩完。於是緊急動員,當晚重啟壓力測試,力爭把問題解決。

由於之前測試部門做壓力測試的時候我不在場,所以今天測試的時候先讓他們演示的一遍,當loadrunner跑到100的時候,問題出來了,網站訪問開始變慢,計數器webservice/current connections急劇上升,直到1000左右,這是訪問網站報503錯誤。這一次我只是為了看下現象,我和小伙伴們都沒有做任何處理。

在再次開啟loadrunner之前,我和小伙伴們就早早各自做好了准備,有些添加計數器,觀察計數器,期望可以看出端倪,而我比較喜歡windbg這個東西,因為她從來沒欺騙過我,我相信這次也不例外。終於在並發達到100,網站拋出503的時候,我敲下了adplus,終於抓住了第一手資料。

下面一起來分析這個dump吧,首先我的思路是這樣的,並發了只有100,但是已經拒絕服務,而且current connections竟然達到1000,說明iis處理不過來導致隊列越來越長 ,超出了隊列 允許的最大長度,所以拋出503,那為什么iis處理不過來呢,因為程序有問題,有某個地方成為了瓶頸,如果用windbg來看的話,應該大部分的線程都卡在了同一個地方。

首先打開windbg,選擇抓到的dump文件

先加載sos.dll

0:000> .load  sos

再看看所有線程的clr堆棧,看看所有的線程運行到哪里了

0:000> ~* e !clrstack

-------------大部分的線程最后運行的程序出現了下面這段-----------------------

OS Thread Id: 0x32bc (65)
Child SP IP Call Site
07ffe6b0 7c95845c [InlinedCallFrame: 07ffe6b0]
07ffe6ac 7a9f07ad DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
07ffe6b0 7a9994a2 [InlinedCallFrame: 07ffe6b0] System.Net.UnsafeNclNativeMethods+OSSOCK.recv(IntPtr, Byte*, Int32, System.Net.Sockets.SocketFlags)
07ffe6f8 7a9994a2 System.Net.Sockets.Socket.Receive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.Net.Sockets.SocketError ByRef)
07ffe730 09c8a654 Enyim.Caching.Memcached.PooledSocket+BasicNetworkStream.Read(Byte[], Int32, Int32)
07ffe754 7a1b9b31 System.IO.BufferedStream.Read(Byte[], Int32, Int32)
07ffe770 0556dcfe Enyim.Caching.Memcached.PooledSocket.Read(Byte[], Int32, Int32)
07ffe7b0 09c8a237 Enyim.Caching.Memcached.GetHelper.ReadItem(Enyim.Caching.Memcached.PooledSocket)
07ffe800 09c8969e Enyim.Caching.Memcached.GetOperation.ExecuteAction()
07ffe814 09c895ba Enyim.Caching.Memcached.Operation.Execute()
07ffe83c 09c894fc Enyim.Caching.MemcachedClient.Get(System.String)
07ffe86c 09c8948e MemcachedProviders.Cache.MemcachedCacheProvider.Get(System.String)
07ffe87c 09c83efc XXX.Caching.MemcachedCacheProvider.XXX.Caching.ICacheProvider.Get(System.String)
07ffe888 09c83d0a XXX.Caching.CacheManager.Get(System.String)
07ffe8b8 09c83c70 XXX.Caching.CacheManager.Get[[System.__Canon, mscorlib]](System.String)

..................這里省略若干行.................

這以為着什么,意味着MemCached成為了最后的執行點,成為了瓶頸,於是找來同事商量下,同事也認為極有可能,最后我們修改配置,改為啟用。net自帶的緩存 。

再次運行loadrunner,並發200毫無壓力,增加到並發500,依然杠杠的。最后我們再看代碼研究問題,一致認為是我們過分依賴MemCached,把所有能緩存的數據都放入了MemCached,大部分需要取數據的地方都經過了MemCached,MemCached成為了瓶頸,可笑嗎,使用MemCached本來是希望提高性能的,結果倒成了瓶頸。

本文重點不在討論問題,而在解決問題的方式。有一段時間沒有用windbg了,有點生了,也許是該整理一下各種關於windbg的案例。這東西和正則一樣,不用就忘。

 

 

    

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM