部落格:http://elf8848.iteye.com
Struts2、SpringMVC、Servlet(Jsp)效能對比 測試 。
Servlet的效能應該是最好的,可以做為參考基準,其它測試都要向它看齊,參照它。
做為一個程式員,對於各個架構的效能要有一個基本的認知,便於選型時做出正確的決策。
在測試中發現了什麼也不要大喊大叫,因為這些都是Java程式員的基礎知識。 人人都要瞭解。
---------------------------------------------------------------------------------------
建議先閱讀《你想建設一個能承受500萬PV/每天的網站嗎? 》一文,瞭解一些測試的基本概念。在測試開始前就有一個效能好與壞的標準。再用這個標準來檢驗你程式。
---------------------------------------------------------------------------------------
測試環境說明:
伺服器: 4G記憶體,至強3.0 (4核超執行緒)CPU,windows 2003
測試機:筆記本 2G記憶體,p8600 雙核CPU,windows XP
網路:100Mb區域網路
測試軟體:
Jmeter 2.3.4 分配了512M記憶體
tomcat 6 預設記憶體大小
---------------------------------------------------------------------------------------
測試組態如: 其實jmeter還是很弱的,我開啟"集合點(synchronizing Timer)","察看結果樹","用表格查看結果"中的任何一個都會導致測試結果中的效能下降和小部分請求的響應出錯(可能是線程數太多了),所以禁用了。只啟用了cookie管理器。
---------------------------------------------------------------------------------------
Tomcat6.0 設定檔的說明 ,做測試之前是要整清楚的。
預設的Server.xml中如下
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 ,也就是Tomcat最多同時使用500個線程處理500個並發(伺服器CPU不錯,500沒問題),不要發生 排隊等待的情況以免影響測試成績, 為下面的壓力測試做好準備。
---------------------------------測試開始了-------------------------------------------
測試時伺服器CPU使用率 10%
測試時測試機CPU使用率 100%(測試機不行啊,主要是 Jmeter的效能一般,又吃記憶體,測試機p8600 雙核CPU還是很強的 )
每次測試CPU都這樣,就統一寫這裡了。
測試1:JSP頁面--2213個請求/秒
100並發,迴圈100次,共10000個請求,請求一個大小3.34KB的jsp頁面。
測試2:JSP頁面--1889個請求/秒
100並發,迴圈100次,共10000個請求,請求一個servlet總控制器,驗證許可權後(很簡單),new一個Action,再轉寄到一個大小3.34KB的jsp頁面。
測試3:HTML頁面--2607個請求/秒
100並發,迴圈100次,共10000個請求,請求一個3.2KB的html頁面。
測試4: HTML頁面-- 833個請求/秒
100並發,迴圈100次,共10000個請求,請求一個13.4KB的html頁面。與上面比是只是檔案大了一些,把網卡跑滿了 ,網卡成為了效能瓶頸,RPS降了不少!!
測試5: Spring MVC 2012個請求/秒
100並發,迴圈100次,共10000個請求,請求一個spring3 MVC的action,再轉寄到一個0.8K的JSP,其內容是簡單的html
測試6: Spring MVC 1800-1924個請求/秒
100並發,迴圈100次,共10000個請求,請求一個spring3 MVC的action,兩個參數類型轉換為int、Date,再new 一個List,再轉寄到一個1.3K的JSP,用JSTL標籤顯示List中的內容。
JSTL標籤內容是如下,看來JSTL標籤效能還是不錯的。
Java代碼
- <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} </td>
- <td align="center">${s.index} </td>
- <td align="center">${item} </td>
- </tr>
- </c:forEach>
- </c:if>
測試7: 訪問一張圖片(srping方式一) 1997個請求/秒
100並發,迴圈100次,共10000個請求. 因為我使用了spring3 MVC,攔截/,所以圖片不能訪問,所以添加了:
Xml代碼
- <servlet-mapping>
- <servlet-name>default</servlet-name>
- <url-pattern>*.jpg</url-pattern>
- </servlet-mapping>
走預設的servlet,來訪問2.5K的圖片
測試8: 訪問一張圖片 (srping方式二) 1967個請求/秒
100並發,迴圈100次,共10000個請求,因為我使用了spring3 MVC,攔截/,所以圖片不能訪問,所以添加了:
<mvc:resources mapping="/images/**" location="/images/" cache-period="31556926"/>
來訪問2.5K的圖片,會走spring的可匹配的一個攔截器。
測試9:Struts2 使用官方提供的樣本程式 (使用了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標籤--s:property) 1192個請求/秒
上一個測試結果糟糕的太離譜了,第二天,想了想又開始重新測試,使用的還是struts2官方提供的struts2-blank-2.1.8.1.war樣本。
訪問下面的action: http://192.168.0.5/struts2/example/HelloWorld.action ,action內容很簡單就是轉寄到一個JSP。
是使用官方樣本中預設的action,我沒有修改,結果如
這裡要說一說轉寄到的jsp中的內容,其中有struts2標籤,如下:
Xml代碼
- <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>
測試11:Struts2 官方提供的 樣本程式 (不使用Struts2標籤) 1976個請求/秒--優秀啊
我把“測試10”中的jsp檔案內容改了,刪除了所有的struts2標籤,只輸出一行文本,測試結果如:
天啊,效能超出我的想像,效能太好了,達到了我的要求。看來一定是struts2標籤拖了後腿。
測試12:Struts2 官方提供的 樣本程式 (使用Struts2標籤--s:form) 426個請求/秒
為了讓現象複現,我把 “測試10”中 jsp又改了,jsp中換用了其它的struts2標籤 ,測試結果如:
使用的標籤是:
Xml代碼
- <s:form action="Login">
- <s:textfield key="username"/>
- <s:password key="password" />
- <s:submit/>
- </s:form>
=====================================================
結論:
struts2架構效能很好, 但struts2的標籤效能太差了。 要避免使用 struts2標籤。
Struts2 由於採用了 值棧、OGNL運算式、struts2標籤庫等,會導致效能下降,很嚴重的下降。如果避免或減少使用這些,效能還是很好的。
Struts2的 多層攔截器、 多執行個體action效能都很好,並不是 導致效能問題的原因。
註:以上測試都沒有資料庫,也沒有複雜業務,action和jsp中內容很簡單,目的就是測試MVC部分的效能。
---------------------------------------------------------------------------------------
其它測試文章:
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 ( C ) |
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 |