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也許也是個不錯的框架!(個人觀點)