MVC性能測試

你想建設一個能承受500萬PV/每天的網站嗎? 
500萬PV是什麼概念?我的服務器每秒要處理多少個請求? 

PV是什麼? 
PV是page view的簡寫。PV是指頁面刷新的次數,每一次頁面訪問,就算做一次pv流量。 

計算模型: 
每臺服務器每秒處理請求的數量=((80%*總PV量)/(24小時*60分*60秒*40%))/服務器數量 
其中關鍵的參數是80%、40%。表示一天中有80%的請求發生在40%的時間內。24小時的40%是9.6小時,有80%的請求發生一天的9.6個小時當中(很適合互聯網的應用)。 

((80%*500萬)/(24小時*60分*60秒*40%))/1 = 1157個請求/秒 
((80%*100萬)/(24小時*60分*60秒*40%))/1 = 231個請求/秒 


結論: 
現在我們在做壓力測試時,就有了標準,如果你的服務器一秒能處理1157個請求,就可以承受500萬PV/每天。這裏不關心是請求的是靜態的html,還是動態的jsp。 
如果你的服務器一秒能處理231個請求,就可以承受100萬PV/每天. 

說明:這裏說明每秒N個請求,更像是TPS。而不是請求一個html頁面而附帶請求的css,js,圖片。因爲我關心的是應用程序處理業務的能力。 


--------------------------------------------------------------------------------------- 
基本概念: 
Throughput(吞吐量):按照常規理解網絡吞吐量表示在單位時間內通過網卡數據量之和,其中即包括本機網卡發送出去的數據量也包括本機網卡接收到的數據量。 
併發用戶數:是同時執行操作的用戶 
響應時間:對請求作出響應所需要的時間 
--------------------------------------------------------------------------------------- 
JMeter測試參數說明: 

Label:每一個測試單元的名字。 

#Samples:表示一個測試單元一共發出了多少個請求。 

Average:平均響應時間——默認情況下是單個 Request 的平均響應時間,當使用了 Transaction Controller 時,也可以以Transaction 爲單位顯示平均響應時間。,不重要。 

Median:中位數,也就是 50% 用戶的響應時間,如果把響應時間從小到大順序排序,那麼50%的請求的響應時間在這個範圍之內。重要。 

90% Line:90% 用戶的響應時間,如果把響應時間從小到大順序排序,那麼90%的請求的響應時間在這個範圍之內。重要。 

Min:最小響應時間,不重要。 

Max:最大響應時間,出現機率只不過是千分之一甚至萬分之一,不重要。 

Error%:本次測試中出現錯誤的請求的數量 

Throughput:吞吐量——默認情況下表示每秒完成的請求數(Request per Second),當使用了 Transaction Controller 時,也可以表示類似 LoadRunner 的 Transaction per Second 數 

KB/Sec:每秒從服務器端接收到的數據量,相當於LoadRunner中的Throughput/Sec 
--------------------------------------------------------------------------------------- 
loadrunner測試參數說明: 

響應時間:
 取90%值,如果把響應時間從小到大順序排序,那麼90%的請求的響應時間在這個範圍之內。重要。 

每秒點擊數 :hits per Second,每秒鐘向服務器提交請求的數量。 

TPS: Transaction per Second ,每秒事務數,一個事務是指一個客戶機向服務器發送請求然後服務器做出反應的過程 

Throughput(吞吐量): Loadrunner記錄的Throughput是接收到服務器返回的所有字節數之和,與本地發出的字節數無關。 

Throughput/Sec: 每秒的吞吐量。 


對於BS架構的一般分析 響應時間、點擊率、吞吐量、TPS(每秒事務數)。 
對於CS架構的一般分析 TPS(每秒事務數) 

--------------------------------------------------------------------------------------- 

Apache ab測試參數說明: 

RPS:
 Request per Second,每秒處理的請求數 

詳見: 
http://blog.chinaunix.net/u3/108043/showart_2260477.html 
--------------------------------------------------------------------------------------- 


測試配置如下圖: 其實jmeter還是很弱的,我打開"集合點(synchronizing Timer)","察看結果樹","用表格查看結果"中的任何一個都會導致性能下降和小部分請求的響應出錯(可能是線程數太多了),所以禁用了。只啓用了cookie管理器。 


--------------------------------------------------------------------------------------- 
Tomcat6.0 配置文件的說明 ,做測試之前是要整清楚的。 
默認的Server.xml中如下 
<Connector port="8080" maxHttpHeaderSize="8192" 
maxThreads="150" minSpareThreads="25" maxSpareThreads="75" 
enableLookups="false" redirectPort="8443" acceptCount="100" 
connectionTimeout="20000" disableUploadTimeout="true" /> 


enableLookups 
是否允許DNS查詢,當web應用程序要通過域名服務器查找機器名轉換爲IP地址時。會使用DNS查詢,需要佔用網絡,延長較長 
maxThreads 
Tomcat可創建的最大的線程數,每一個請求須要一個線程來處理,原來的150太小了,我們測試時併發會超過他的。 
acceptCount 
指定當所有可以使用的處理請求的線程數都被使用時,可以放到處理隊列中的請求數,就是被排隊的請求數,超過這個數的請求將拒絕連接。 
connnectionTimeout 
網絡連接超時,單位:毫秒。設置爲0表示永不超時,這樣設置有隱患的。通常可設置爲20000毫秒。 
minSpareThreads 
Tomcat初始化時創建的線程數 
maxSpareThreads 
一旦創建的線程中空閒線程超過這個值,Tomcat就會關閉不再需要的socket線程。 

注意:maxThreads 設置爲500,也就是最多有500個線程,爲下一步的壓力測試做好準備。 

--------------------------------------------------------------------------------------- 

測試環境說明: 
服務器: 4G內存,至強3.0 (4核超線程)CPU,windows 2003 
測試機:筆記本 2G內存,p8600 CPU,windows XP 
網絡:100Mb局域網 
測試軟件: 
Jmeter 2.3.4    分配了512M內存 
tomcat 6  默認內存大小 
--------------------------------------------------------------------------------------- 
測試時服務器CPU使用率 10% 
測試時測試機CPU使用率 100%(測試機不行啊) 
每次測試CPU都這樣,就統一寫這裏了。 

測試1:2213個請求/秒 
100併發,循環100次,共10000個請求,請求一個大小3.34KB的jsp頁面。 



測試2:1889個請求/秒 
100併發,循環100次,共10000個請求,請求一個servlet總控制器,驗證權限後,new一個Action,再轉發到一個大小3.34KB的jsp頁面。 



測試3:2607個請求/秒 
100併發,循環100次,共10000個請求,請求一個3.2KB的html頁面。 



測試4: 833個請求/秒 
100併發,循環100次,共10000個請求,請求一個13.4KB的html頁面。與上面比是隻是文件大了一些,性能就降了不少!! 



測試5: spring   2012個請求/秒 
100併發,循環100次,共10000個請求,請求一個spring3 MVC的action,再轉發到一個0.8K的JSP,其內容是簡單的html 



測試6: spring   1800-1924個請求/秒 
100併發,循環100次,共10000個請求,請求一個spring3 MVC的action,兩個參數類型轉換爲int、Date,再new 一個List,再轉發到一個1.3K的JSP,用JSTL標籤顯示List中的內容。 

JSTL標籤內容是如下,看來JSTL標籤性能還是不錯的。 
<c:if test="${empty list}"> 
<tr> 
<td align="center">無記錄!</td> 
</tr> 
</c:if> 
<c:if test="${not empty list}"> 
<tr> 
<th>從 1 開始的迭代計數</th> 
<th>從 0 開始的迭代計數</th> 
<th>產品名稱</th> 
</tr> 
<c:forEach items="${list}" var="item" varStatus="s"> 
<tr bgcolor=${s.index%2==0?"#E2E2E2":""}> 
<td align="center">${s.count}&nbsp;</td> 
<td align="center">${s.index}&nbsp;</td> 
<td align="center">${item}&nbsp;</td> 
</tr> 
</c:forEach> 
</c:if> 


測試7: 圖片   1997個請求/秒 
100併發,循環100次,共10000個請求. 因爲我使用了spring3 MVC,攔截/,所以圖片不能訪問,所以添加了: 
<servlet-mapping>      
    <servlet-name>default</servlet-name>      
    <url-pattern>*.jpg</url-pattern>      
</servlet-mapping> 
走默認的servlet,來訪問2.5K的圖片 



測試8: 圖片   1967個請求/秒 
100併發,循環100次,共10000個請求,因爲我使用了spring3 MVC,攔截/,所以圖片不能訪問,所以添加了: 
<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/> 
來訪問2.5K的圖片,會走spring的可匹配的一個攔截器。 


測試9:Struts2的測試 
100併發,循環1次,沒有循環100次,因爲strtus2在這次測試中響應太慢了,我等不起了,所以單個url的測試樣本從10000降到了100.一共11個url,共1100個樣本。 
"spring" 使用的就是前面“測試5”的URL,放在這裏是爲了與strtus2對比的。 
"html"   使用的就是前面“測試3”的URL,放在這裏是爲了與strtus2對比的。 
"struts2-1" 使用的是官方自帶的示例項目,名稱是struts2-blank-2.1.8.1.war 
"struts2-2" 使用的是官方自帶的示例項目,名稱是struts2-showcase-2.1.8.1.war,我在其中隨便選了一個action來做測試 
"struts2-3" 同上 
"struts2-4" 同上 
"struts2-5" 同上 
"struts2-6" 同上 
"struts2-7" 同上 
"struts2-8" 同上 
"struts2-9" 同上 
太忙了,沒有時間對Struts2做優化,使用的都是官方帶的示例,Struts2的測試結果不理想,放在這裏做一個參考。“struts2-1”是struts2中測試成績最好的,但也不理想。 



測試10:Struts2的測試。 
上一個測試結果太離譜了,第二天,想了想又重新測試了下,使用的還是struts2官方提供的struts2-blank-2.1.8.1.war示例。訪問下面的action,action內容簡單就是轉發到一個JSP。 
http://192.168.0.5/struts2/example/HelloWorld.action 

下圖是示例默認的action,我沒有修改: 

要說一說轉發到的jsp,其中有struts2標籤 
<s:property value="message"/> 
<s:url id="url" action="HelloWorld"> 
     <s:param name="request_locale">en</s:param> 
</s:url> 
<s:a href="%{url}">English</s:a> 

我把jsp改了,刪除了所有struts2標籤,只輸出一行文件 

天啊,性能超出我的想像,太好了。看來是struts2標籤拖了後腿。 

我把jsp改了,換了其它的struts2標籤 

標籤是: 
<s:form action="Login"> 
    <s:textfield key="username"/> 
    <s:password key="password" /> 
    <s:submit/> 
</s:form> 
看來struts2的標籤性能太差了。 

Struts2由於採用了 值棧、OGNL表達式、struts2標籤庫等,會導致性能下降。如果避免或減少使用這些,性能還是很好了。 
Struts2的
 多層攔截器、 多實例action不是導致性能問題的原因。 


注:以上測試都沒有數據庫,也沒有業務,action中,jsp中內容很簡單。 

--------------------------------------------------------------------------------------- 

其它測試文章: 
http://zhaoshg.iteye.com/blog/356231 
http://www.iteye.com/topic/679543 

MVC框架性能比較 
http://wenku.baidu.com/view/148d7e34eefdc8d376ee32ac.html 

spring3mvc與struts2比較 
http://www.iteye.com/topic/646240 



附:
幾種標籤和框架組合解析數據時候的 性能測試對比

一、 數據

數據通過查詢日誌表得到數據,共 1302 條數據,將查詢出的數據放入一個靜態 List 中,保證每次請求的數據相同。

測試頁面的元素相同,只是在取數據方式上不同。

二、 測試目標

1、  JSP 頁面使用 struts2 標籤的性能;

2、  JSP 頁面使用 JSTL 標籤的性能;

3、  Freemarker 頁面使用 struts2 標籤的性能;

4、  Freemarker 頁面使用 JSTL 標籤的性能;

5、  Freemarker 頁面使用其本身的數據加載方式的性能。

三、 加載耗時對比

時間: ms           注:每一次對比都是在同一時間段按同一順序依次執行下列幾種方式

 

 

struts2

JSTL ( 

Freemarker-struts2

Freemarker-C

Freemarker

第一次

306

58

1618

 

41

第二次

202

52

1643

 

39

第三次

211

58

2047

 

36

第四次

196

49

1621

 

28

第五次

218

52

1607

 

40

第六次

303

331

1857

 

45

第七次

210

50

1671

 

33

第八次

311

51

1699

 

47

第九次

462

55

2180

 

37

第十次

218

46

1721

 

42

平均值

263.7

80.2

1766.4

 

38.8

去掉最高和最低

223.75

53.125

1547.125

 

39.125

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章