前後端搭配的測試
各種前端的,我在這裡要測試的性能主要是對於動態請求的響應速度,所以本案中的某些配置既沒有考慮使用Rewrite或其他方式對靜態文件進行單獨處理 (除了Passenger和Swiftiply默認配置便實現了這個功能),也不考慮測試到前端的KeepAlive請求。主要測試以下的組合:- Apache + Passenger
- Nginx + Mongrel
- Nginx + Evented Mongrel
- Nginx + Thin
- Swiftiply + Swiftiplied Mongrel
- Swiftiply + Thin
- HAproxy + Mongrel
- HAproxy + Thin
- Lighttpd + Mongrel
- Lighttpd + Thin
- Lighttpd + FastCGI/Socket
- Lighttpd + FastCGI/TCP
前端和後端處於同一台機器上,所有的後端都設為10個進程,綁定於30000-30009端口,Passenger設置為最大生成10個進程,Swiftiply則是綁定於4000端口監聽。FastCGI的socket路徑為/tmp/rails[0-9].sock。
各種部署方式的性能排個名次,以下是後各種方案在並發量>=10的情況下的平均值(去掉出現0值的情況):
前端 | 後端 | 平均每秒響應數 | 最大鏈接限制 |
Lighttpd | FastCGI/TCP | 215.33 | 64 |
Lighttpd | FastCGI/Socket | 214.65 | 64 |
Lighttpd | Thin | 196.16 | 64 |
Swiftiply | Swiftiplied Mongrel | 191.33 | N/A |
HAproxy | Thin | 188.73 | 10 |
Swiftiply | Thin(Swiftiplied) | 178.96 | N/A |
Apache2.2/Prefork | Passenger | 173.02 | N/A |
HAproxy | Mongrel | 170.4 | 1 |
Apache2.2/Worker | Passenger | 163.9 | N/A |
Lighttpd | Mongrel | 149.85 | 64 |
Nginx | Evented Mongrel | 149.78 | N/A |
Nginx | Thin | 143.88 | N/A |
Nginx | Mongrel | 138.86 | N/A |
在這個表中,Lighttpd的三種方案佔據了前三位,Lighttpd+FastCGI是性能最高的部署方式。這種方式比另一種流行方案Nginx+Mongrel的方式性能提升了高達50%!
FastCGI的好處在此體現出來:
- 二進制協議,無需HTTP的解析
- 與前端可以建立持久鏈接
- 沒有鎖和上下文切換的開銷
Lighttpd+Thin的方式的性能列第三位,這點似乎出乎意料之外,但實際上是因為Lighttpd 1.5支持對HTTP後端建立HTTP KeepAlive鏈接。在第一部分對後端單獨的測試中,小並發下的Thin的KeepAlive測試性能並不比FastCGI差,同時Thin實現了非 阻塞IO,而FastCGI則是阻塞式的。相反,HAproxy和Nginx則都不支持HTTP KeepAlive。
而Swiftiply的方式也顯示出了強勁的性能,應該是得益於它的「讓後端主動連接到Swiftiply」的這種特殊的結構。
當前備受關注的Passenger的部署方式在本案中並沒有顯示出特別的性能上的優勢,不過如果將並發鏈接數放在300以內,則 Apache2.2/Prefork + Passenger的部署方式的平均每秒響應數上升為204.03,這樣看來,倘若為Apache進行一些優化配置,依然不失為一種高效的部署方案。而同 時Passenger又是最容易配置的一種方案,能達到這種效果已經非常令人滿意。
HAproxy + Mongrel並限制鏈接數為1,則是一種穩定、保守的部署方式,雖然在這裡性能不出眾,但是穩定性非常好。
最後,與Nginx相關的三種方案都排在了該榜的末尾,由於Nginx的反向代理負載均衡缺少一些高級的特性以及Rails本身的特性而導致其不適合單獨應用在Rails程序的部署上:
- 缺少到後台服務器端的鏈接數限制的能力,這導致了Mongrel在接受大量請求時將時間消耗在上下文切換和鎖的爭用上。
- 缺乏建立到後台服務器端的持久鏈接的能力,這導致了在鏈接的打開、建立、關閉上花費了額外的開銷。