溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java Web服務(wù)性能優(yōu)化的實踐分析

發(fā)布時間:2021-10-29 16:47:26 來源:億速云 閱讀:154 作者:柒染 欄目:編程語言

本篇文章為大家展示了Java Web服務(wù)性能優(yōu)化的實踐分析,內(nèi)容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

簡介: 如何提升 Java Web 服務(wù)性能,主要介紹了三種方法:一是采用 Web 服務(wù)的異步調(diào)用,二是引入 Web 服務(wù)批處理模式,三是壓縮 SOAP 消息。重點介紹在編程過程中如何使用異步 Web 服務(wù)以及異步調(diào)用和同步調(diào)用的差異點。本文還示范了如何在項目中使用以上三種方法,以及各種方法所適合的應(yīng)用場景。

Java Web 服務(wù)簡介

Web 服務(wù)是一種面向服務(wù)架構(gòu)的技術(shù),通過標(biāo)準(zhǔn)的 Web 協(xié)議提供服務(wù),目的是保證不同平臺的應(yīng)用服務(wù)可以互操作。Web 服務(wù)(Web Service)是基于 XML 和 HTTP 通訊的一種服務(wù),其通信協(xié)議主要基于 SOAP,服務(wù)的描述通過 WSDL、UDDI 來發(fā)現(xiàn)和獲得服務(wù)的元數(shù)據(jù)。 這種建立在 XML 標(biāo)準(zhǔn)和 Internet 協(xié)議基礎(chǔ)上的 Web 服務(wù)是分布式計算的下一步發(fā)展方向,Web 服務(wù)為那些由不同資源構(gòu)建的商業(yè)應(yīng)用程序之間的通信和協(xié)作帶來了光明的前景,從而使它們可以彼此協(xié)作,而不受各自底層實現(xiàn)方案的影響。

JAX-RPC 1.0 是 Java 方面的 Web 服務(wù)的原始標(biāo)準(zhǔn) , 但是由于 JAX-RPC 1.0 對 Web 服務(wù)功能的認(rèn)識有一定的局限,于是 JAX-WS 2.0 應(yīng)用而生。JAX-WS 2.0 開發(fā)工作的主要目標(biāo)是對各項標(biāo)準(zhǔn)進行更新,成功實現(xiàn)了業(yè)界對 JAX-RPC 1.X 的各種期望。此外,JAX-WS 2.0 直接支持 XOP/MTOM,提高了系統(tǒng)附件傳送能力以及系統(tǒng)之間的互操作性。

實例剖析Web服務(wù)性能瓶頸

通過以上簡述不難體會到,Web 服務(wù)以其 XML + HTTP 的松耦合、平臺無關(guān)的特性,集萬般寵愛于一身,必將成為未來數(shù)據(jù)共享的基礎(chǔ)。但與此同時我們也應(yīng)當(dāng)認(rèn)識到世間完事萬物均有其矛盾的兩面性:有優(yōu)點,必將存在缺點,Web 服務(wù)亦是如此。就像當(dāng)初 JAVA 大行其道的時候性能成為其致命詬病一樣,Web 服務(wù)也同樣面臨性能問題,似乎“性能問題”天生就是“平臺無關(guān)”揮之不去的冤家。但問題終歸要解決,實踐是檢驗和分析問題的唯一途徑,讓我們先來創(chuàng)建一個簡單的 Web 服務(wù)再來審視和分析隱含其中的性能問題。

創(chuàng)建服務(wù)

創(chuàng)建服務(wù) Java Bean: 首先我們創(chuàng)建一個盡可能簡單的書店服務(wù) Bean,服務(wù)的內(nèi)容只有一個 qryBooksByAuthor,即根據(jù)作者 (Author) 查詢其名下的書籍 (List<Book>)。

圖 1. 書店服務(wù) Bean(BookStoreSrvBean)

Java Web服務(wù)性能優(yōu)化的實踐分析

服務(wù) Input- 作者 (Author) 的實體類 :

圖 2. 作者實體類 (Author)

Java Web服務(wù)性能優(yōu)化的實踐分析

服務(wù)出參 Output- 書籍 (Book) 列表的實體類:

圖 3. 書籍實體類 (Book)

Java Web服務(wù)性能優(yōu)化的實踐分析

至此我們的服務(wù)代碼已經(jīng)完成,我們不在此討論此服務(wù)的業(yè)務(wù)合理性,創(chuàng)建此服務(wù)的目的只是舉一個盡可能簡單的實例以分析 web 服務(wù)的性能。

下面的任務(wù)就是開發(fā) Web 服務(wù)了,手工編寫及發(fā)布符合規(guī)范的 Web 服務(wù)過程極為繁瑣,在此使用 IBM 的 Rational Software Architect(后面簡稱 RSA)來進行 Web 服務(wù)的服務(wù)器端以及客戶端的開發(fā)。

發(fā)布 Web 服務(wù)

創(chuàng)建動態(tài) Web 項目 : 發(fā)布 Web 服務(wù)的前提當(dāng)然需要一個 J2EE 的 Web 項目,打開 RSA->File->New->Dynamic Web Project, 項目名稱為 testWebService, 其余選項根據(jù)需要進行選擇 ( 注意需要選擇加入 Web 項目到 EAR)。創(chuàng)建好的 Web 項目和 EAR 項目效果如下 :

圖 4. Web 項目以及應(yīng)用項目的結(jié)構(gòu)

Java Web服務(wù)性能優(yōu)化的實踐分析

創(chuàng)建 Web 服務(wù): 選中導(dǎo)入的 com.ibm.test.ws.srv.BookStoreSrvBean,右鍵 New->Other->Web Service 來創(chuàng)建并發(fā)布 Web 服務(wù)。創(chuàng)建的時候選擇常用的 JAX-WS 標(biāo)準(zhǔn) , 并選擇生成 WSDL 文件。由于 Web 服務(wù)的創(chuàng)建不是本文重點,此部分內(nèi)容暫且省略。服務(wù)創(chuàng)建完成之后就可以發(fā)布到上一步建好的 Web 項目中了。

創(chuàng)建客戶端

使用 RSA,客戶端的創(chuàng)建工作將會非常簡單:右鍵點擊上面生成的 WSDL 文件 ->Web Services->Generate Client

圖 5. 創(chuàng)建客戶端界面

Java Web服務(wù)性能優(yōu)化的實踐分析

在此界面,根據(jù)實際情況選擇 server,JAX-WS 標(biāo)準(zhǔn)以及 Client 代碼的目標(biāo)項目,然后點擊下一步。

圖 6. 輸入客戶端信息

Java Web服務(wù)性能優(yōu)化的實踐分析

此界面暫時使用默認(rèn)配置,某些特殊選項將在后面章節(jié)進行描述。

客戶端調(diào)用

由于 JAX-WS 規(guī)范大部分的 stub 調(diào)用代碼是實時生成的,我們只需要修改客戶端 WSDL 的 port 就可以用以下代碼進行 Web 服務(wù)的調(diào)用。這里修改 WSDL 端口的目的是讓客戶端調(diào)用 RSA 提供的 TCP/IP Monitor 的虛擬端口,這樣我們就可以很輕易地看到 Web 服務(wù)實際的調(diào)用以及返回的 SOAP 消息了。

客戶端調(diào)用代碼如下 :

圖 7. 客戶端調(diào)用代碼

Java Web服務(wù)性能優(yōu)化的實踐分析

使用 TCP/IP Monitor 看到的 SOAP 消息如下 :

圖 8. Web 服務(wù)調(diào)用產(chǎn)生的 SOAP 消息

Java Web服務(wù)性能優(yōu)化的實踐分析

Java Web 服務(wù)性能分析

從以上實例我們可以看到,Web 服務(wù)的調(diào)用與傳統(tǒng)的 RPC 還是有較大差異的。最大的特點是調(diào)用雙方使用 XML 格式的 SOAP 規(guī)范消息進行傳輸,這樣以文本進行傳輸?shù)暮锰幨菕仐壛怂接袇f(xié)議,無論調(diào)用雙方是何種平臺,只要能夠構(gòu)造以及解析 XML 文本,并且存在雙方都支持的傳輸協(xié)議,那么調(diào)用就成為了可能。而 XML 的日益規(guī)范以及 HTTP 協(xié)議的普及更是給這兩個必要條件提供了堅強的后盾,Web 服務(wù)成為未來通用的服務(wù)提供標(biāo)準(zhǔn)已是不爭的事實。

但是相信使用過 Web 服務(wù)的人都曾經(jīng)經(jīng)受過其性能不佳的窘境,原因為何我們結(jié)合剛才的實例可以分析出以下幾點:

● SOAP 文本消息轉(zhuǎn)化導(dǎo)致效率低下

從剛才的 TCP/IP Monitor 監(jiān)測到的 request 以及 response 的消息我們可以看到,在發(fā)送消息時,我們傳入了 Author 對象,在實際的調(diào)用發(fā)生時,這個 Author 對象會被轉(zhuǎn)化成 XML 格式的 SOAP 消息,此消息在到達 Server 端會被解析并重新構(gòu)造成 Server 端的 Author 對象。Response 也是同理,Books List 也會經(jīng)歷 XML 序列化和反序列化的過程。最糟糕的是,這種過程會在每一次調(diào)用的時候都會發(fā)生,這種構(gòu)造以及解析的過程都會極大地消耗 CPU,造成資源的消耗。

●SOAP 文本消息傳輸導(dǎo)致傳輸內(nèi)容膨脹

以 request 參數(shù) Author 為例,必要的信息僅僅是”Bruce Eckel”這幾個字節(jié),但轉(zhuǎn)化成 XML 消息后,可以從 SOAP 消息看到,多了很多 SOAP 規(guī)范的標(biāo)簽,這些信息會導(dǎo)致需要傳輸?shù)膬?nèi)容急劇增大,幾個字節(jié)很可能會變成幾千字節(jié)。當(dāng)調(diào)用頻度和參數(shù)內(nèi)容增多的時候,這種傳輸內(nèi)容的膨脹將不是一個可以忽略的影響,它不但會吃掉網(wǎng)絡(luò)的帶寬,還會給 Server 的數(shù)據(jù)吞吐能力造成負(fù)擔(dān),后果可想而知。

●同步阻塞調(diào)用在某些情況下導(dǎo)致性能低下

同步阻塞調(diào)用是指客戶端在調(diào)用 Web 服務(wù)發(fā)送 request 后一直處于阻塞狀態(tài),客戶端線程就會掛起,一直處于等待狀態(tài),不能進行其他任務(wù)的處理。這樣就會造成線程的浪費,如果相應(yīng)線程占用了一些資源,也不能夠及時釋放。

這個問題在純客戶端訪問 Server 端的情況下并不明顯,但如果是兩個 Server 端之間進行 Web 服務(wù)調(diào)用的話,阻塞模式就會成為調(diào)用 Server 端的性能瓶頸。

Web 服務(wù)性能優(yōu)化實踐

使用異步方式調(diào)用 web 服務(wù)

先需要強調(diào)一點的是,這里的異步方式指的是客戶端的異步,無論客戶端是同步還是異步,都對服務(wù)端沒有任何影響。我們期望的理想結(jié)果是:當(dāng)客戶端發(fā)送了調(diào)用請求后不必阻塞等待 server 端的返回結(jié)果。最新的 JAX-WS 標(biāo)準(zhǔn)中增加了這一異步調(diào)用的特性,更好的消息是,RSA 工具中也對 JAX-WS 的這一特性進行了支持,這樣就極大地方便了我們進行異步調(diào)用客戶端的創(chuàng)建。

其實講客戶端配置為異步模式極其簡單,只要在 RSA 生成 Client 端代碼時將&lsquo; Enable asynchronous invocation for generated client &rsquo; 選中即可 , 如下圖 :

圖 9. 異步客戶端創(chuàng)建選項

這樣在生成的客戶端的 BookStoreSrvBeanService 中就會多了 qryBooksByAuthorAsync 的異步方法。既然是異步方法,回調(diào) (Call Back) 就是必不可少的,在下面的異步客戶端測試代碼中可以看到匿名內(nèi)部類作為回調(diào) handler 的具體使用方法 :

圖 10. 異步客戶端調(diào)用示例代碼

Java Web服務(wù)性能優(yōu)化的實踐分析

測試代碼的輸出結(jié)果如下:

圖 11. 異步調(diào)用控制臺輸出

Java Web服務(wù)性能優(yōu)化的實踐分析

可以看到,當(dāng) Web 服務(wù)沒有返回時,客戶端仍然有機會做自己的輸出 :“not done yet, can do something else&hellip;”。有些人可能會認(rèn)為作為客戶端此處的輸出并無實際意義,但試想如果一個 server 作為客戶端去訪問一個 Web 服務(wù),如果在服務(wù)等待期間能夠有機會脫離阻塞狀態(tài)執(zhí)行自己需要的代碼,甚至可以使用 wait 等方法釋放被當(dāng)前線程占用的資源,那么對于此 server 來說這將是一個對性能提升起到本質(zhì)作用的因素。

使 web 服務(wù)支持批處理模式

● 批處理模式簡介

批處理顧名思義是采用一次性處理多條事務(wù)的方式來取代一次一條事務(wù)的傳統(tǒng)處理方式。Java Database Connectivty (JDBC) 中提供了大量的批處理 API 用于優(yōu)化數(shù)據(jù)庫操作性能,例如 Statement.executeBatch() 可以一次性接收并執(zhí)行多條 SQL 語句。批處理思想可以方便的移植到 Web 服務(wù)調(diào)用場景以達到優(yōu)化 Web 服務(wù)調(diào)用響應(yīng)的目的。通過實際 Web 服務(wù)調(diào)用時間戳分析不難看出網(wǎng)絡(luò)通訊是 Web 服務(wù)性能的瓶頸之一,因此通過減少網(wǎng)絡(luò)通訊開銷來優(yōu)化 Web 服務(wù)性能,批處理模式是其中較為直接的一種實現(xiàn)方式。

批處理模式適應(yīng)性

批處理模式雖然作用顯著,但是也不適合所有場景。使用批處理模式處理 Web 服務(wù)請求時需要考慮一下幾點:

1.不同 Web 服務(wù)執(zhí)行時間差異性

不同 Web 服務(wù)執(zhí)行時間不盡相同,因此在同時處理多 Web 服務(wù)請求時需要考慮這種時間差異性。一般情況下是等待最長處理時間的 Web 服務(wù)執(zhí)行完畢后匯總所有 Web 服務(wù)執(zhí)行結(jié)果從而返回到客戶端,因此存在批處理多 Web 服務(wù)反而比順序單次調(diào)用 Web 服務(wù)消耗更長時間可能性。需要在采用批處理模式前對 Web 服務(wù)性能有清晰的了解,盡可能將性能參數(shù)相似的 Web 服務(wù)納入批處理,而分別處理執(zhí)行時間差異較大的 Web 服務(wù)。一般建議將性能差異在 30% 以內(nèi)的多 Web 服務(wù)可以考慮納入批處理。比方說 AccountWebService 中有一個獲取用戶賬戶列表的 Web 服務(wù) getUserAccounts,這個 Web 服務(wù)執(zhí)行需要 15 秒,另外 UserWebService 中有一個獲取用戶目前 pending 的待處理通知 getUserPendingNotifications,這個 Web 服務(wù)執(zhí)行需要 2 秒時間,我們可以看到這兩個 Web 服務(wù)執(zhí)行時間差異較大,因此在這種情況下我們不建議將這兩個 Web 服務(wù)納入批處理。而 AccountWebService 中有一個增加第三方用戶賬號的 Web 服務(wù) addThirdPartyNonHostAccount,該 Web 服務(wù)執(zhí)行需要 3 秒,此時就就可以考慮能將 getUserPendingNotifications Web 服務(wù)和 addThirdPartyNonHostAccount 放在一個批處理中一次性調(diào)用處理。

2.不同 Web 服務(wù)業(yè)務(wù)相關(guān)性

一般情況下建議考慮將存在業(yè)務(wù)相關(guān)性的多 Web 服務(wù)放入批處理中,只有業(yè)務(wù)存在相關(guān)性的多 Web 服務(wù)才會涉及到減少調(diào)用次數(shù)以提高應(yīng)用系統(tǒng)性能的需求。比方說用戶在增加第三方賬號 addThirdPartyNonHostAccount 以后會默認(rèn)自動發(fā)送一條 pending 的 notification 給用戶用以提示用戶來激活增加的賬號,因此這種場景下可以完美的將 addThirdPartyNonHostAccount Web 服務(wù)和 getUserPendingNotifications Web 服務(wù)放入一個批處理中,在用戶增加完三方賬號后系統(tǒng)自動刷新 pending notification 區(qū)域以提示用戶激活賬號。UserWebService 中有一個獲取用戶主賬號的 Web 服務(wù) getUserHostAccounts 和獲取用戶三方賬號的 Web 服務(wù) getUserNonHostAccounts,MetaDataService 中有一個獲取國家金融機構(gòu)假期數(shù)據(jù)的 Web 服務(wù) getFinacialAgencyHolidays,該 Web 服務(wù)明顯和 getUserHostAccounts,getUserNonHostAccounts 不存在業(yè)務(wù)上相關(guān)性,因此不應(yīng)該將它們納入批處理。

3.盡量避免將存在依賴關(guān)系的多 Web 服務(wù)放入同一個批處理中

將多個存在依賴關(guān)系的多 Web 服務(wù)放入同一批處理中需要專門考慮、處理多 Web 服務(wù)彼此間的依賴關(guān)系,進而無法將方便的這些 Web 服務(wù)并發(fā)執(zhí)行而不得不串行執(zhí)行有依賴關(guān)系的 Web 服務(wù),最悲觀情況下批處理響應(yīng)時間將是批處理中所有 Web 服務(wù)串行執(zhí)行時間和。原則上即使批處理中 Web 服務(wù)間存在依賴關(guān)系,通過動態(tài)指定依賴關(guān)系也可以實現(xiàn)多 Web 服務(wù)的批處理調(diào)用。但是這樣將大大增加批處理實現(xiàn)的技術(shù)復(fù)雜性,因此不建議如此操作。

4.多線程方式處理批處理 Web 服務(wù)請求

批處理模式在服務(wù)實現(xiàn)端一般通過多線程處理方法來并發(fā)處理多個 Web 服務(wù)調(diào)用請求。通過集中的解析器解析批處理模式請求,之后針對每一個 Web 服務(wù)調(diào)用會啟動一個單獨的線程來處理此 Web 請求,同時會有一個總的線程管理器來調(diào)度不同 Web 服務(wù)執(zhí)行線程,監(jiān)控線程執(zhí)行進度等。在所有線程執(zhí)行完成后匯總 Web 服務(wù)執(zhí)行結(jié)果返回客戶端。

批處理實現(xiàn)方式

批處理實現(xiàn)方式一般有兩種:靜態(tài)批處理模式,動態(tài)批處理模式:

靜態(tài)批處理模式實現(xiàn)較為簡單,但是相對缺乏靈活性。靜態(tài)批處理的核心思想就是在已有 Web 服務(wù)的基礎(chǔ)上通過組合封裝的方式來得到批處理的目的。舉例來說將系統(tǒng)中已有的 Web 服務(wù)請求結(jié)構(gòu)組合成一個新的數(shù)據(jù)對象模型作為 Web 服務(wù)批處理請求結(jié)構(gòu),在客戶端進行批處理調(diào)用時通過初始化批處理請求數(shù)據(jù)對象,并將特定的 Web 服務(wù)請求對象賦值給批處理請求對象屬性的方式。同理在服務(wù)實現(xiàn)端在生成批處理響應(yīng)數(shù)據(jù)對象時也是通過將具體 Web 服務(wù)的響應(yīng)組合起來生成并返回客戶端。

動態(tài)批處理模式實現(xiàn)較為復(fù)雜,但也能提供更大的操作靈活性。動態(tài)批處理模式一般需要應(yīng)用采用 Java 反射 API 開發(fā)具有容器功能的批處理實現(xiàn)框架。客戶端可以動態(tài)的向容器中增加 Web 服務(wù)調(diào)用請求,比方說客戶端可以動態(tài)的將 addThirdPartyNonHostAccount,getUserPendingNotifications 兩個 Web 服務(wù)加入到這個容器中然后發(fā)起一個框架提供的批處理 Web 服務(wù)調(diào)用請求。該批處理 Web 服務(wù)在實現(xiàn)端將解析容器并將其中的各個 Web 服務(wù)請求抽取解析并啟動獨立的線程來處理。

壓縮SOAP

當(dāng) Web Service SOAP 消息體比較大的時候,我們可以通過壓縮 soap 來提高網(wǎng)絡(luò)傳輸性能。通過 GZIP 壓縮 SOAP 消息,得到二進制數(shù)據(jù),然后把二進制數(shù)據(jù)作為附件傳輸。以前常規(guī)方法是把二進制數(shù)據(jù) Base64 編碼,但是 Base64 編碼后的大小是二進制數(shù)據(jù)的 1.33 倍。辛苦壓縮的,被 Base64 給抵消差不多了。是否可以直接傳輸二進制數(shù)據(jù)呢? JAX-WS 的 MTOM 是可以的,通過 HTTP 的 MIME 規(guī)范, SOAP message 可以字符,二進制混合。我們在 client 和 server 端各注冊一個 handler 來處理壓縮和解壓。 由于壓縮后的 SOAP 消息附件與消息體中的部分不是基于 MTOM 自動關(guān)聯(lián)的,需要單獨處理附件。在生成 client 端和 server 端代碼的時候需要 enable MTOM。 Handler 具體代碼在本文代碼附件中, test.TestClientHanlder, test.TestServerHanlder。 寫好了 handler 了之后還要為 service 注冊 handler。

客戶端 handler 樣例代碼如下:

客戶端代碼

public boolean handleMessage(MessageContext arg0) {          SOAPMessageContext ct = (SOAPMessageContext) arg0;          boolean isRequestFlag = (Boolean) arg0                  .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);          SOAPMessage msg = ct.getMessage();          if (isRequestFlag) {              try {                  SOAPBody body = msg.getSOAPBody();                  Node port = body.getChildNodes().item(0);                  String portContent = port.toString();                  NodeList list = port.getChildNodes();                  for (int i = 0; i < list.getLength(); i++) {                      port.removeChild(list.item(i));                  }                  ByteArrayOutputStream outArr = new ByteArrayOutputStream();                  GZIPOutputStream zip = new GZIPOutputStream(outArr);                  zip.write(portContent.getBytes());                  zip.flush();                  zip.close();                  byte[] arr = outArr.toByteArray();                  TestDataSource ds = new TestDataSource(arr);                  AttachmentPart attPart = msg.createAttachmentPart();                  attPart.setDataHandler(new DataHandler(ds));                  msg.addAttachmentPart(attPart);              } catch (SOAPException e) {                  e.printStackTrace();              } catch (IOException e) {                  e.printStackTrace();              }          }          return true;      }

Web 服務(wù)端 handler 樣例代碼如下:

服務(wù)端代碼

public boolean handleMessage(MessageContext arg0) {          SOAPMessageContext ct = (SOAPMessageContext) arg0;          boolean isRequestFlag = (Boolean) arg0                  .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);          SOAPMessage msg = ct.getMessage();          if (!isRequestFlag) {              try {                  Object obj = ct.get("Attachments");                  Attachments atts = (Attachments) obj;                  List list = atts.getContentIDList();                  for (int i = 1; i < list.size(); i++) {                      String id = (String) list.get(i);                      DataHandler d = atts.getDataHandler(id);                      InputStream in = d.getInputStream();                      ByteArrayOutputStream out = new ByteArrayOutputStream();                      GZIPInputStream zip = new GZIPInputStream(in);                      byte[] arr = new byte[1024];                      int n = 0;                      while ((n = zip.read(arr)) > 0) {                          out.write(arr, 0, n);                      }                      Document doc = DocumentBuilderFactory.newInstance()                              .newDocumentBuilder()                              .parse(new ByteArrayInputStream(out.toByteArray()));                      SOAPBody body = msg.getSOAPBody();                      Node port = body.getChildNodes().item(0);                      port.appendChild(doc.getFirstChild().getFirstChild());                  }              } catch (SOAPException e) {                  e.printStackTrace();              } catch (IOException e) {                  e.printStackTrace();              } catch (SAXException e) {                  e.printStackTrace();              } catch (ParserConfigurationException e) {                  e.printStackTrace();              }          }          return true;      }

在 web.xml 中 service-ref 部分添加 handler. Server 端 handler 也是同樣添加。

配置代碼

<handler-chains>              <handler-chain>                  <handler>                      <handler-name>TestClientHandler</handler-name>                      <handler-class>test.TestClientHandler   </handler-class>                  </handler>              </handler-chain>          </handler-chains>

上述內(nèi)容就是Java Web服務(wù)性能優(yōu)化的實踐分析,你們學(xué)到知識或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識儲備,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI