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中如下
- <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標籤性能還是不錯的。
- <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,攔截/,所以圖片不能訪問,所以添加了:
- <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標籤,如下:
- <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標籤 ,測試結果如下圖:
使用的標籤是:
- <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 |