1摘要
開發webservice應用程序中離不開框架的支持,當open-open網站列舉的就有很多種,這對於開發者如何選擇帶來一定的疑惑。性能Webservice的關鍵要素,不同的框架性能上存在較大差異,而當前在官方網站、網絡資料中可以方便的找到各自框架的介紹,但是很少有針對不同框架性能測試數據。本文選擇了比較流行幾個框架:
Apache Axis1、Apache Axis2、Codehaus XFire、Apache CXF、Apache Wink、Jboss RESTEasy、sun JAX-WS(最簡單、方便)、阿里巴巴 Dubbo(除外)等,采用Java作為測試用例,通過本機和遠程兩種進行測試方式,對這幾種框架進行了性能測試,並對測試結果分析和性能比較,最后並對性能優異的框架進行了推薦。
目前三種主流的web服務實現方法:
REST(新型):表象化狀態轉變 (軟件架構風格)RESTEasy、Wink、CXF、Axis2…….
SOAP(比較成熟):簡單對象訪問協議 Xfire、Axis2、CXF、Axis1
XML-RPC(淘汰):遠程過程調用協議(慢慢被soap 所取代)
REST 簡單易用,效率高,貌似未來有很大的發展空間,也有宣稱rest性能個方便比soap強大的,已經有很多框架宣稱對rest進行支持比如spring 3.0、struts…….. (百度觀點)
SOAP 成熟度較高,安全性較好
關鍵詞:Axis1、Axis2、XFire、CXF、Spring、SOAP、StAX、WSDL
2 框架介紹
2.1 Apache Axis1
Axis本質上就是一個SOAP引擎(Apache Axis is an implementation of the SOAP),提供創建服務器端、客戶端和網關SOAP操作的基本框架。但Axis並不完全是一個SOAP引擎,它還包括:
l 是一個獨立的SOAP服務器。
l 是一個嵌入Servlet引擎(例如Tomcat)的服務器。
l 支持WSDL。
l 提供轉化WSDL為Java類的工具。
l 提供例子程序。
l 提供TCP/IP數據包監視工具。
2.2 Apache Axis2
Apache Axis2相比Apache Axis1更加有效、更加模塊化、更加面向xml,支持容易插件模塊擴展新功能和特性,例如安全和可靠。Apache Axis2是基於Apache AXIOM,它是一個高性能、pull-based XML對象模型。Apache Axis2的關鍵特性:
l 解析xml更快。采用自己的對象模型和StAX (Streaming API for XML)。
l 更低的內存占用。
l 支持熱部署。新服務加入到系統,無需重啟服務。
l 支持異步webservice、
l MEP支持,靈活支持在WSDL 2.0定義的Message Exchange Patterns (MEPs)
l 更加靈活。引擎給開發人員提供了充足的自由度可擴展客戶頭信息處理、系統管理、
l 更加穩定性。
l 傳輸框架不依賴於具體協議。為集成和傳輸協議(SMTP, FTP, message-oriented middleware, etc)有一個簡單和抽象,引擎核心是完全獨立於具體的傳輸協議。
l 支持WSDL。支持WSDL1.1、WSDL2.0。
l 方便集成其他組件(Add-ons)。幾個web services已經被集成,包括:WSS4J for security (Apache Rampart), Sandesha for reliable messaging, Kandula which is an encapsulation of WS-Coordination, WS-AtomicTransaction and WS-BusinessActivity.
l 良好的擴展性。
2.3 Codehaus XFire
XFire核心是一個輕量的基於STAX消息處理模型,用來與SOAP消息交互,它支持不同類型的綁定機制、容器和傳輸協議。
支持webservice標准- SOAP, WSDL, WS-I Basic Profile, WS-Addressing, WS-Security, etc.
l 高性能SOAP STACK
l 可插拔綁定POJOs, XMLBeans, JAXB 1.1, JAXB 2.0, and Castor support
l 通過Java1.5 和1.4(Commons attributes JSR 181 syntax)使用JSR 181 API配置服務
l 支持多中傳輸協議- HTTP, JMS, XMPP, In-JVM, etc.
l 可嵌入的和直觀的API
l 支持Spring, Pico, Plexus, and Loom
l 支持JBI
l 客戶端和服務端stub代碼生成
l 支持JAX-WS early access
2.4 Apache CXF
Apache CXF是一個開源服務框架。Apache CXF = Celtix + XFire,Apache CXF 的前身叫 Apache CeltiXfire,現在已經正式更名為 Apache CXF 了,以下簡稱為 CXF。CXF 繼承了Celtix和XFire兩大開源項目的精華,比如:JAX-WS and JAX-RS,主要特性包括:
l 支持Web services標准。包括:SOAP、the WSI Basic Profile、WSDL、WS-Addressing、WS-Policy、WS-ReliableMessaging、WS-Security、WS-SecureConversation和WS-SecurityPolicy.
l 支持不同類型前端開發模型。CXF實現了JAX-WS APIs,支持JAX-RS開發。
l 容易使用。CXF設計的簡潔和直觀,具有簡潔APIs迅速的構建基於代碼的服務,Maven插件使得工具集成更加容易、JAX-WS API支持、Spring 2.x XML使得配置更加容易。
l 支持二進制和遺留協議。CXF被設計為可插拔的架構,在不同的傳輸協議結合下,不僅支持XML,也支持非XML類型綁定,例如:JSON和CORBA。
2.5 RESTEasy(百度觀點較好)
RESTEasy是JBoss的一個開源項目,提供各種框架幫助你構建RESTful Web Services和RESTful Java應用程序。它是JAX-RS規范的一個完整實現並通過JCP認證。作為一個JBOSS的項目,它當然能和JBOSS應用服務器很好地集成在一起。但是,它也能在任何運行JDK5或以上版本的Servlet容器中運行。RESTEasy還提供一個RESTEasy JAX-RS客戶端調用框架。能夠很方便與EJB、Seam、Guice、Spring和Spring MVC集成使用。支持在客戶端與服務器端自動實現GZIP解壓縮。 (資料少無法比較)
有較專業的人士對CXF、Restlet、RESTEasy、Jersey框架測試【數據】,他說從性能上看RESTEasy是最好的,Jersey其次(但Jersey連可查閱的英文文檔都比較少故個人不推薦使用),cxf和Restlet最差,
2.6 Dubbo (個人觀點----無理由)
Dubbo是阿里巴巴公司開源的一個高性能優秀的服務框架,使得應用可通過高性能的 RPC 實現服務的輸出和輸入功能,可以和 Spring框架無縫集成。(資料少無法比較)
2.7 java6JAX-WS
JAX-WS2.0 (JSR 224)是Sun新的web services協議棧
JAVA中有三種WebService規范,分別是JAX-WS(JAX-RPC)、JAX-RS、JAXM&SAAJ。
JAX-WS(Java API For XML-WebService),JDK1.6 自帶的版本為JAX-WS2.1,其底層支持為JAXB。早期的JAVA Web服務規范JAX-RPC(Java API ForXML-Remote Procedure Call)目前已經被JAX-WS 規范取代,JAX-WS 是JAX-RPC 的演進版本,但JAX-WS 並不完全向后兼容JAX-RPC。()
2.8 Apache Wink
REST(Representational State Transfer) based Web Service【http://baike.soso.com/v812054.htm】是相對於傳統的Web Service(SOAP+WSDL+UDDI)而提出的。傳統的Web Service可以很好的解決異構系統之間的通信問題,但是需要首先定義好XML格式的合同(WSDL),client和server都必須嚴格遵守協議,不容易升級以及集群伸縮。REST Web Service不需要事先定義格式,傳輸的內容也可以依據不同的client變化(json,xml,html等),最重要的是使用源URL來唯一定位資源,對資源的增刪改查映射為HTTP的四個方法,無狀態傳輸,具有非常好的伸縮性。
Apache Wink就是一個純Java的REST框架。它完整的實現了JSR 311並擴展了部分功能,此外還提供了良好的擴展性,難能可貴的是還可以與流行的Java框架Spring無縫集成。目前該項目還在開發中。所謂框架無非就是定義好格式,提供一些工具和鈎子,讓開發人員可以專注於業務邏輯的開發。
3 測試准備
表格1測試基本元素
測試條件 |
描述 |
主機環境 |
A測試機:CPU:1.60GHz;內存:1.37G |
B測試機:CPU:1.83GHz;內存:1G |
|
Web服務 |
axis1 1.3 |
axis2 1.2 |
|
xfire 1.2.6 |
|
應用環境 |
jdk 1.4、spring 2.x |
客戶端代碼 |
public void testgetVersion() throws java.lang.Exception { |
服務端代碼 |
public String getVersion() |
測試方法 |
本機接口測試,客戶端和服務端都在A測試機上進行; |
遠程接口測試,A測試機作為客戶端,B測試機作為服務器。本次測試是在局域網內完成。 |
|
結果精度 |
數字精確到小數點后兩位 |
名詞解釋 |
服務器端:部署到服務器的程序。 |
客戶端:發起請求調用服務器上webservcie的程序。 |
|
客戶端初時化時間:發起接口調用時,初始化客戶端java對象所需時間。 |
表格2在端對端性能上,一個客戶端驅動程序使用了一個胖客戶端Web服務堆棧來發送和接受SOAP請求
Webservice服務端 |
Webservice客戶端 Webservice stack |
SOAP over HTTP |
4 性能測試
4.1 測試方法
本次假定在相同網絡、主機環境條件下進行測試,因此性能的差別主要是由不同框架實現機制的所決定。
l 采用兩種方式測試:本機測試、遠程測試。
l 服務器端分別采用:axis1、axis2、xfire、CXF,對於選定的服務器端,用不同框架對應的工具包wsdl生成客戶端stub代碼進行測試。
l 服務端接口內部沒有復雜業務邏輯,客戶端調用時,僅僅返回一個字符串。
l 每次運行,采用java循環方式調用10次服務端接口,並記錄下從發起到返回結果的時間。
4.2 測試結果
限於篇幅,本文僅提供了:以CXF框架為服務端的詳細測試結果,及其各個框架的綜合后測試結果。
表格3以CXF作為服務端測試詳細結果
本機測試結果(單位:ms) |
||||||||||||
服務器端 |
cxf |
|||||||||||
客戶端 |
cxf |
axis1 |
||||||||||
客戶端初始化 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
||
2547 |
2594 |
2563 |
2578 |
2563 |
2569 |
422 |
422 |
407 |
406 |
421 |
415.6 |
|
連續10次調用接口測試 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
||
1 |
297 |
281 |
281 |
282 |
266 |
281.4 |
234 |
219 |
219 |
234 |
219 |
225 |
2 |
0 |
0 |
0 |
15 |
15 |
0 |
16 |
0 |
0 |
16 |
||
3 |
0 |
16 |
16 |
0 |
0 |
16 |
15 |
16 |
16 |
0 |
||
4 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
15 |
||
5 |
16 |
0 |
0 |
0 |
0 |
15 |
16 |
15 |
0 |
0 |
||
6 |
0 |
15 |
15 |
0 |
16 |
0 |
0 |
0 |
16 |
0 |
||
7 |
0 |
0 |
0 |
0 |
0 |
16 |
16 |
16 |
0 |
16 |
||
8 |
15 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
15 |
0 |
||
9 |
0 |
0 |
0 |
0 |
15 |
16 |
15 |
16 |
0 |
16 |
||
10 |
0 |
16 |
16 |
15 |
0 |
0 |
0 |
0 |
16 |
0 |
||
10次平均值 |
32.8 |
32.8 |
32.8 |
31.2 |
31.2 |
32.16 |
29.7 |
29.7 |
28.2 |
29.7 |
28.2 |
29.61 |
后9次平均值 |
3.444 |
5.222 |
5.222 |
3.333 |
5.111 |
4.467 |
7 |
8.667 |
7 |
7 |
7 |
7.333 |
遠程測試結果(單位:ms) |
||||||||||||
服務器端 |
cxf |
|||||||||||
客戶端 |
cxf |
axis1 |
||||||||||
客戶端初始化 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
||
2703 |
2547 |
2578 |
2563 |
2531 |
2584 |
406 |
406 |
422 |
407 |
422 |
412.6 |
|
連續10次調用接口測試 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
第1組 |
第2組 |
第3組 |
第4組 |
第5組 |
||
1 |
344 |
281 |
281 |
281 |
297 |
296.8 |
219 |
234 |
235 |
234 |
687 |
321.8 |
2 |
0 |
0 |
16 |
16 |
16 |
16 |
0 |
15 |
16 |
16 |
||
3 |
0 |
16 |
0 |
0 |
0 |
62 |
16 |
0 |
0 |
0 |
||
4 |
16 |
0 |
16 |
15 |
0 |
47 |
16 |
16 |
15 |
16 |
||
5 |
0 |
15 |
0 |
0 |
15 |
16 |
15 |
15 |
16 |
0 |
||
6 |
0 |
0 |
15 |
16 |
0 |
31 |
0 |
0 |
0 |
15 |
||
7 |
0 |
16 |
0 |
0 |
16 |
16 |
16 |
16 |
15 |
0 |
||
8 |
15 |
0 |
0 |
0 |
0 |
31 |
0 |
16 |
16 |
16 |
||
9 |
0 |
16 |
16 |
15 |
0 |
31 |
15 |
0 |
0 |
0 |
||
10 |
0 |
0 |
0 |
0 |
15 |
31 |
16 |
15 |
16 |
15 |
||
10次平均值 |
37.5 |
34.4 |
34.4 |
34.3 |
35.9 |
35.3 |
50 |
32.8 |
32.8 |
32.8 |
76.5 |
43.37 |
后9次平均值 |
3.444 |
7 |
7 |
6.889 |
6.889 |
6.244 |
31.22 |
10.44 |
10.33 |
10.44 |
8.667 |
14.22 |
表格4不同框架本機和遠程測試結果
本機測試結果(單位:ms) |
||||||||
服務器端 |
axis2 |
axis1 |
xfire |
cxf |
||||
客戶端 |
axis2 |
axis1 |
axis1 |
axis2 |
xfire+spring |
axis1 |
cxf |
axis1 |
客戶端初始化 |
656.4 |
1138 |
1325 |
762.2 |
0 |
1340.6 |
2569 |
451.6 |
10次中的初次調用值 |
546.4 |
568.8 |
484.2 |
434.8 |
1022 |
987.4 |
281.4 |
225 |
10次平均值 |
62.48 |
66.7 |
73.44 |
57.22 |
119.2 |
120.9 |
32.16 |
29.61 |
后9次平均值 |
8.71 |
11.84 |
27.8 |
15.27 |
18.84 |
25 |
4.467 |
7.333 |
遠程測試結果(單位:ms) |
||||||||
客戶端初始化 |
672.8 |
1040 |
axis1 |
772 |
0 |
2994 |
2584 |
421.6 |
10次中的初次調用值 |
645.8 |
606 |
684.4 |
427.8 |
1010 |
1190 |
296.8 |
321.8 |
10次平均值 |
71.58 |
70.36 |
97.82 |
60.28 |
117.2 |
139.1 |
35.3 |
43.37 |
后9次平均值 |
7.78 |
10.58 |
32.64 |
19.44 |
18.04 |
27.13 |
6.244 |
14.22 |
4.3 結果分析
從數據可以看出,有下面幾個特點:
l 客戶端初次調用,初始化客戶端stub對象時,大約在:600ms~2500ms。由於需要建立網絡連接,初始化java相關對象,因此耗時較長。
l 客戶端初始化stub后,接口初次調用,大約在:400ms~1000ms。相比后續的接口調用時間最長。
l 在第一次調用完畢后,隨后的調用中,性能都明顯提升。大約在:7ms~30ms。
l 本機測試與遠程測試,性能上差距很微小,在高速的局域網內,性能差別幾乎可以忽略。
l 在相同的服務端下,采用不同框架生成的stub代碼調用時,時間上也存在一定的差異。
實際應用中,接口的調用都是在網絡的不同的機器之間進行,本文也重點關注遠程調用測試結果,在測試結果比較上,可以看出:
l 最優組合是最差組合性能的5倍多。
n 最優的組合為:cxf客戶端+ cxf服務端,6ms左右。
n 最差的組合為:axis1客戶端+ axis1服務端,32ms左右。
l CXF作為服務端,對於不同的客戶端調用時,性能最佳。
從以上的結果進行分析得出用Axis2與CXF作為服務器端效率是比兩外兩者(Axis1與xfire)要高,所以下面就對CXF與Axis2進行對比
5 選擇框架的方法
1. 選擇能夠對我們的開發過程提供更多、更好幫助的Web開發框架
(CXF與Axis2都是apache的開源框架,也是目前比較流行的webservice框架,)(百度加個人觀點)
2. 開發框架的學習一定要簡單,上手一定要快,沒有什么比使用能得到更深的體會。那些動不動就需要半個月或者一個月學習周期的框架,實在是有些恐怖。(cxf學習成本比axis2低)【Axis2允許自己作為獨立的應用來發布Web Service,並提供了大量的功能和一個很好的模型,這個模型可以通過它本身的架構(modular architecture)不斷添加新的功能。有些開發人員認為這種方式對於他們的需求太過於繁瑣。這些開發人員會更喜歡CXF。 】【CXF更注重開發人員的工效(ergonomics)和嵌入能力(embeddability)。大多數配置都可以API來完成,替代了比較繁瑣的XML配置文件, Spring的集成性經常的被提及,CXF支持Spring2.0和CXF's API和Spring的配置文件可以非常好的對應。CXF強調代碼優先的設計方式(code-first design),使用了簡單的API使得從現有的應用開發服務變得方便。】{百度觀點}
3. 一定要能得到很好的技術支持,在應用的過程中,或多或少都會出現這樣或者那樣的問題,如果不能很快很好的解決,會對整個項目開發帶來影響。一定要考慮綜合成本,其實這是目前應用開源軟件最大的問題,碰到問題除了死肯文檔就是查閱源代碼,或者是網上搜尋解決的辦法,通常一個問題就會導致1-2天的開發停頓,嚴重的甚至需要一個星期或者更長,一個項目有上這么幾次,項目整體的開發成本嗖嗖的就上去了。(所以個人感覺應該選擇比較流行的框架,起碼碰到問題還能上網搜索)
4. 開發框架結合其他技術的能力一定要強(個人感覺和下同)
5. 開發框架的擴展能力一定要強。在好的框架都有力所不及的地方,這就要求能很容易的擴展開發框架的功能,以滿足新的業務需要。同時要注意擴展的簡單性,如果擴展框架的功能代價非常大,還不如不用呢。(axis2與cxf 都支持很多優秀的框架(上已提到),但axis2擴展性比cxf要好,axis2不僅支持java對c/C++提供支持)(個人觀點)【RESTEasy也能支持許多比較優秀的框架】(百度加個人觀點)
6. 開發框架最好能提供可視化的開發和配置,可視化開發對開發效率的提高,已經得到業界公認。(暫時無法提供觀點)
7. 開發框架的設計結構一定要合理,應用程序會基於這個框架,框架設計的不合理會大大影響到整個應用的可擴展性。(暫時無法提供觀點)
8. 開發框架一定要是運行穩定的,運行效率高的。框架的穩定性和運行效率直接影響到整個系統的穩定性和效率。(從上面的測試來看,cxf的效率要高於axis2,不知道在大並發量的時候系統的穩定性和安全性)
9. 開發框架一定要能很好的結合目前公司的積累。在多年的開發中已有了很多積累,不能因為使用開發框架就不能再使用了,那未免有些得不償失。(暫時無法提供觀點)
10. 選擇開發框架另外要注意的一點就是:任何開發框架都不可能是十全十美的,也不可能是適應所有的應用場景的,也就是說任何開發框架都有它適用的范圍。所以選擇的時候要注意判斷應用的場景和開發框架的適用性。(暫時無法提供觀點)
6 結束語
Apache CXF是CodehausXFire的第二代產品,目前在不同框架中性能最佳,應該是開發者不錯的選擇,這與它本身的架構設計不無關系。相比其他框架,CXF具有幾個突出的特性:支持JAX-WS、Spring集成、Aegi數據綁定、支持RESTful services、支持WS-*、Apache協議、代碼實現簡潔。
Apache Axis2是Apache Axis1的第二代產品,架構上也非常不錯,關鍵特性:支持多語言(C/C++)、支持各種規范、可插拔模塊化設計、支持熱部署等。與CXF相比性能也非常優異。
RESTEasy也許也是個不錯的框架!(個人觀點)