Rails2.3版本發布了,這個版本內部的改動非常大,相關介紹可以看JavaEye這篇新聞:http://www.javaeye.com/news/5390,估計最近也有不少人開始動手升級到Rails2.3了,JavaEye也不例外,這一升級才發現效能低得令人髮指。
由於過於信任Rails架構,沒有進行本地效能測試,在通過了相容性測試就興沖衝上線了。這一上線,動態請求立刻堵了一大堆,仔細看了看fastcgi的crash
log,發現大量請求在flush資料的時候發生broen
pipe。開啟Rails2.3新採用的Rack架構原始碼當中fastcgi的adapter一看,這代碼寫的太不負責了!fastcgi協議本身是沒有設定緩衝區的,寫出去的資料立刻就發送掉了,結果Rack還非常多餘的在每次寫資料之後flush一下,造成了串連已經關閉之後,fastcgi還傻傻的等著flush資料呢!
自行修改了Rack的fastcgi
adapter,本地運行壓力測試,fastcgi不再報錯,代碼上線發布,立刻又堵住了,load非常高,這下開始懷疑是不是Rack的fastcgi支援的不好,導致的效能差?
由於thin是對Rack支援最好的Rails應用伺服器,因此我們把網站rails運行方式從fastcgi改成了thin,再次代碼上線發布,又堵住了,而且堵的更嚴重,load比剛才用fastcgi還要高很多!
由此也可以看出來,fastcgi畢竟還是Rails效能最好的運行方式。
完全排除了fastcgi的問題,又排查了好幾處可能造成效能影響的地方,還是無法解決rails2.3一上線請求就被堵塞的問題。最後老老實實在本地進行了效能測試,這下終於真相大白。在我本地MacOSX的環境下面,rails2.2的情況下每秒可以處理40個請求,但是rails2.3每秒只能處理25個請求,同時CPU消耗的更多,進程記憶體佔用更高!
最後真正的原因是Rails2.3內建的memcache-client有重大效能問題
簡單的來說,Rails2.2內建的memcache-client是1.5.0版本,這是一個用了很久很穩定的版本了,也是目前
memcache-client官方正式發布版本;而Rails2.3的memcache-client升級到了1.6.5版本,這是一個全新的版本,僅僅在github上面,並未正式發布,可以看成一個開發當中的版本,而這個版本有無數的問題!
第一、它設定了一個怪異的timeout參數,預設情況下,導致串連memcache
server的速度變得異常緩慢,把該timeout參數改成nil以後,速度恢複正常
第二、它把串連memcache
server的每個方法操作改成了閉包調用,固然代碼和異常處理顯得優雅一些,但是效能測試表明,整體應用效能會下降很多。
第三、它裡面的代碼還有一些自相矛盾的地方,比方說多線程的檢測和處理代碼有錯誤
總之,在把rails2.3的memcache
client版本換成老的1.5.0版本以後,效能問題得到瞭解決,而且在本地效能測試的結果表明,在rails2.3上面運行JavaEye代碼,速度比rails2.2上面還要提升了11%的效能,但是記憶體消耗有所上升(估計是rails2.3的local
cache帶來的)。
當然memcache-client 1.6.5也不是一無是處,他添加了自動容錯移轉的能力(在多個memcached
server之間),內部代碼也進行了一些重構(儘管重構的結果是效能更低下),添加了一些多線程支援(儘管這部分代碼根本不能正常工作),不過畢竟這還是一個開發當中不成熟的版本,rails不應該很草率的就升級了memcache
client版本。