溫馨提示×

溫馨提示×

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

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

12個最重要的J2EE最佳實踐(2)

發(fā)布時間:2020-08-07 11:53:51 來源:ITPUB博客 閱讀:180 作者:lonlux2 欄目:編程語言

12個最重要的J2EE最佳實踐(2)

[@more@]7. 使用無狀態(tài)會話 bean,而不是有狀態(tài)會話 bean
這樣做可以使您的系統(tǒng)經(jīng)得起錯誤的終止。使用 HttpSession 存儲和用戶相關(guān)的狀態(tài)。

以我們的觀點看來,有狀態(tài)會話 bean 的概念已經(jīng)過時了。如果您仔細對其考慮一下,一個有狀態(tài)會話 bean 實際上與一個 CORBA 對象在體系結(jié)構(gòu)上是完全相同的,無非就是一個對象實例,綁定到一個服務(wù)器,并且依賴于服務(wù)器來管理其生命周期。如果服務(wù)器關(guān)閉了,這種對象也就不存在,那么這個 bean 的客戶端的信息也就不存在。

J2EE 應(yīng)用服務(wù)器為有狀態(tài)會話 bean 提供的故障轉(zhuǎn)移(failover)能夠解決一些問題,但是有狀態(tài)的解決方案沒有無狀態(tài)的解決方案易于擴展。例如,在 WebSphere Application Server 中,對無狀態(tài)會話 bean 的請求,是通過對部署無狀態(tài)會話的成員集群進行平衡加載來實現(xiàn)。相反地,J2EE 應(yīng)用服務(wù)器不能對有狀態(tài) bean 的請求進行平衡加載。這意味著您的集群中的服務(wù)器的加載過程會是不均衡的。此外,使用有狀態(tài)會話 bean 將會再添加一些狀態(tài)到您的應(yīng)用服務(wù)器上,這也是不好的做法。這樣就增加了系統(tǒng)的復(fù)雜性,并且在出現(xiàn)故障的情況下使問題變得復(fù)雜化。創(chuàng)建健壯的分布式系統(tǒng)的一個關(guān)鍵原則是盡量使用無狀態(tài)行為。

因此,我們建議對大多數(shù)應(yīng)用程序使用無狀態(tài)會話 bean 方法。任何在處理時需要使用的與用戶相關(guān)的狀態(tài)應(yīng)該以參數(shù)的形式傳送到 EJB 的方法中(并且通過使用一種機制如 HttpSession 來存儲它)或者從持久性的后端存儲(例如通過使用實體 bean)作為 EJB 事務(wù)的一部分來進行檢索。在合適的情況下,這個信息可以緩存到內(nèi)存中,但是要注意在分布式的環(huán)境中保存這種緩存所潛在的挑戰(zhàn)性。緩存非常適合于只讀數(shù)據(jù)。

總之,您要確保從一開始就要考慮到可伸展性。檢查設(shè)計中的所有設(shè)想,并且考慮到當(dāng)您的應(yīng)用程序要在多個服務(wù)器上運行時,是否也可以正常運行。這個規(guī)則不但適合上述情況的應(yīng)用程序代碼,也適用于如 MBean 和其他管理界面的情況下。

避免使用有狀態(tài)性不只是對 IBM/WebSphere 的建議,這是一個基本的 J2EE 設(shè)計原則。

8. 使用容器管理的事務(wù)

學(xué)習(xí)一下 J2EE 中的兩階段提交事務(wù),并且使用這種方式,而不是開放您自己的事務(wù)管理。容器在事務(wù)優(yōu)化方面幾乎總是比較好的。

使用容器管理的事務(wù)(CMT)提供了兩個關(guān)鍵的優(yōu)勢(如果沒有容器支持這幾乎是不可能的):可組合的工作單元和健壯的事務(wù)行為。

如果您的應(yīng)用程序代碼顯式地使用了開始和結(jié)束事務(wù)(也許使用 javax.jts.UserTransaction 或者甚至是本地資源事務(wù)),而將來的要求需要組合模塊(也許會是代碼重構(gòu)的一部分),這種情況下往往需要改變事務(wù)代碼。例如,如果模塊 A 開始了一個數(shù)據(jù)庫事務(wù),更新數(shù)據(jù)庫,隨后提交事務(wù),并且有模塊 B 做出同樣的處理,請考慮一下當(dāng)您在模塊 C 中嘗試使用上述兩個模塊,會出現(xiàn)什么情況呢?現(xiàn)在,模塊 C 正在執(zhí)行一個邏輯動作,而這個動作實際上將調(diào)用兩個獨立的事務(wù)。如果模塊 B 在執(zhí)行中失敗了,而模塊 A 的事務(wù)仍然能被提交。這是我們所不希望出現(xiàn)的行為。如果,相反地,模塊 A 和模塊 B 都使用 CMT 的話,模塊 C 也可以開始一個 CMT(通常通過配置描述符),并且在模塊 A 和模塊 B 中的事務(wù)將是同一個事務(wù)的隱含部分,這樣就不再需要復(fù)雜的重寫代碼的工作了。

如果您的應(yīng)用程序在同一個操作中需要訪問多種資源,您就要使用兩階段提交事務(wù)。例如,如果從 JMS 隊列中刪除一個消息,并且隨后更新基于這條消息的紀錄,這時,要保證這兩個操作都會執(zhí)行或都不會執(zhí)行就變得尤為重要。如果一條消息已經(jīng)從隊列中被刪除,而系統(tǒng)沒有更新與此消息相關(guān)的數(shù)據(jù)庫中的紀錄,那么這種系統(tǒng)是不穩(wěn)定的。一些嚴重的客戶及商業(yè)糾紛源自不一致的狀態(tài)。

我們時??吹揭恍┛蛻魬?yīng)用程序試圖實現(xiàn)他們自己的解決方案。也許會通過應(yīng)用程序的代碼在數(shù)據(jù)庫更新失敗的時候 "撤銷"對隊列的操作。我們不提倡這樣做。這種實現(xiàn)要比您最初的想象要復(fù)雜得多,并且還有許多其他的情況(想象一下如果應(yīng)用程序在執(zhí)行此操作的過程中突然崩潰的情況)。作為替代的方式,應(yīng)該使用兩階段提交事務(wù)。如果您使用 CMT,并且在一個單一的 CMT 中訪問兩階段提交的資源(例如 JMS 和大多數(shù)數(shù)據(jù)庫),WebSphere 將會處理所有的復(fù)雜工作。它將確保整個事務(wù)被執(zhí)行或者都不被執(zhí)行,包括系統(tǒng)崩潰、數(shù)據(jù)庫崩潰或其他的情況。其實現(xiàn)在事務(wù)日志中保存著事務(wù)狀態(tài)。當(dāng)應(yīng)用程序訪問多種資源的時候,我們怎么強調(diào)使用 CMT 事務(wù)的必要性都不為過。

9. 將 JSP 作為表示層的首選

只有在需要多種表示輸出類型,并且輸出類型被一個單一的控制器及后端支持時才使用 XML/XSLT。

我們常聽到一些爭論說,為什么您選擇 XML/XSLT 而不是 JSP 作為表示層技術(shù)。選擇 XML/XSLT 的人的觀點是,JSP" 允許您將模型和視圖混合在一起",而 XML/XSLT 不會有這種問題。遺憾的是,這種觀點并不完全正確,或者至少不像白與黑那樣分的清楚。實際上,XSL 和 XPath 是編程語言。XSL 是圖靈完成的(Turing-complete),盡管它不符合大多數(shù)人定義的編程語言,因為它是基于規(guī)則的,并且不具備程序員習(xí)慣的控制工具。

現(xiàn)在的問題是既然給予了這種靈活性,開發(fā)人員就會利用這種靈活性。盡管每個人都認同 JSP 使開發(fā)人員容易在視圖中加入"類似模型"的行為,而實際上,在 XSL 中也有可能做出一些同樣的事情。盡管從 XSL 中進行訪問數(shù)據(jù)庫這樣的事情會非常困難,但是我們曾經(jīng)見到過一些異常復(fù)雜的 XSLT 樣式表執(zhí)行復(fù)雜的轉(zhuǎn)換,這實際上是模型代碼。

然而,應(yīng)該選擇 JSP 作為首選的表示技術(shù)的最基本的原因是,JSP 是現(xiàn)在支持最廣泛的、也是最被廣泛理解的 J2EE 視圖技術(shù)。而隨著自定義標記庫、JSTL 和 JSP2.0 的新特性的引入,創(chuàng)建 JSP 變得更加容易,并且不需要任何 Java 代碼,以及可以將模型和視圖清晰的分離開。在一些開發(fā)環(huán)境中(如 WebSphere Studio)加入了對 JSP(包括對調(diào)試的支持)的強大支持,并且許多開發(fā)人員發(fā)現(xiàn)使用 JSP 進行開發(fā)要比使用 XLS 簡單,一些支持 JSP 的圖形設(shè)計工具及其他特征(尤其在 JSF 這樣的框架下)使得開發(fā)人員可以以所見即所得的方式進行 JSP 的開發(fā),而對于 XSL 有時不容易做到。

最后一個要謹慎考慮使用 JSP 的原因是速度問題。在 IBM 所作的對比 XSL 和 JSP 相對速度的性能測試顯示:在大多數(shù)情況下,JSP 在生成同樣的 HTML 的時候,要比 XSL 快好幾倍,甚至使用編譯過的 XSL 也是如此。盡管多數(shù)情況下這不是問題,但在性能要求很高的情況下,這就會成為問題。

然而,這也不能說,您永遠也不要使用 XSL。在一些情況下,XSL 能夠表示一組固定的數(shù)據(jù),并且可以基于不同的樣式表來以不同的方式顯示這些數(shù)據(jù)的能力是顯示視圖的最佳解決方案。然而,這只是一種例外的情況,而不是通用的規(guī)則。如果您只是生成 HTML 來表達每一個頁面,那么在大多數(shù)情況下,XSL 是一種不必要的技術(shù),并且,它給您的開發(fā)人員所帶來的問題遠比它所能解決的問題多。

10. 當(dāng)使用 HttpSession 時,盡量只將當(dāng)前事務(wù)所需要的狀態(tài)保存其中,其他內(nèi)容不要保存在 HttpSession 中。


啟用會話持久性。

HttpSessions 對于存儲應(yīng)用程序狀態(tài)信息是非常有用的。其 API 易于使用和理解。遺憾的是,開發(fā)人員常常遺忘了 HttpSession 的目的----用來保持暫時的用戶狀態(tài)。它不是任意的數(shù)據(jù)緩存。我們已經(jīng)見到過太多的系統(tǒng)為每個用戶的會話放入了大量的數(shù)據(jù)(達到兆字節(jié))。那好了,如果同時有 1000 個登錄系統(tǒng)的用戶,每個用戶擁有 1MB 的會話數(shù)據(jù),那么就需要 1G 或者更多的內(nèi)存用于這些會話。要使這些 HTTP 會話數(shù)據(jù)較小一些,不然的話,您的應(yīng)用程序的性能將會下降。一個大約比較合適的數(shù)據(jù)量應(yīng)該是每個用戶的會話數(shù)據(jù)在 2K-4K 之間,這不是一個硬性的規(guī)則,8K 仍然沒有問題,但是顯然會比 2K 時的速度要慢。一定要注意,不要使 HttpSession 變成數(shù)據(jù)堆積的場所。

一個常見的問題是使用 HttpSession 緩存一些很容易再創(chuàng)建的信息,如果有必要的話。由于會話是持久性的,進行不必要的序列化以及寫入數(shù)據(jù)是一種很奢侈的決定。相反地,應(yīng)該使用內(nèi)存中的哈希表來緩存數(shù)據(jù),并且在會話中保存一個對此數(shù)據(jù)進行引用的關(guān)鍵字。這樣,如果不能成功登錄到另外的應(yīng)用服務(wù)器的話,就可以重新創(chuàng)建數(shù)據(jù)。

當(dāng)談及會話持久性時,不要忘記要啟用這項功能。如果您沒有啟用會話持久性,或者服務(wù)器因為某種原因停止了(服務(wù)器故障或正常的維護),則所有此應(yīng)用服務(wù)的當(dāng)前用戶的會話將會丟失。這是件令人非常不高興的事情。用戶不得不重新登錄,并且重新做一些他們曾經(jīng)已經(jīng)做過的事情。相反地,如果啟用了會話持久性,WebSphere 會自動將用戶(以及他們的會話)移到另外一個應(yīng)用服務(wù)器上去。用戶甚至不知道會有這種事情的發(fā)生。我們曾經(jīng)見到過一些產(chǎn)品系統(tǒng)因為存在于本地代碼中令人難以忍受的 bug(不是 IBM 的代碼?。┒蝗槐罎⒌那闆r,這這種情況下,上述功能仍然可以運行良好。

11. 在 WebSphere 中,使用動態(tài)緩存,并使用 WebSphere servlet 緩存機制。

通過使用這些功能,系統(tǒng)性能可以得到很大的提高,而開銷是很小的。并且不影響編程模型。

通過緩存來提高性能的好處是眾所周知的事情。遺憾的是,當(dāng)前的 J2EE 規(guī)范沒有包括一種用于 servlet/JSP 緩存的機制。然而,WebSphere 提供了對頁面以及片斷緩存的支持,這種支持是通過其動態(tài)緩存功能來實現(xiàn)的,并且不需要對應(yīng)用程序作出任何改變。其緩存的策略是聲明性的,而且其配置是通過 XML 配置描述符來實現(xiàn)的。因此,您的應(yīng)用程序不會受到影響,并保持與 J2EE 規(guī)范的兼容性和移植性,同時還從 WebSphere 的 servlet 及 JSP 的緩存機制中得到性能的優(yōu)化。

從 servet 及 JSP 的動態(tài)緩存機制得到的性能的提高是顯而易見的,這取決于應(yīng)用程序的特性。Cox 和 Martin [Cox] 指出對一個現(xiàn)有的 RDF(資源描述格式)站點摘要 (RSS)servlet,當(dāng)使用動態(tài)緩存時,其性能可以提高 10%。請注意這個實驗只涉及到一個簡單的 servlet,這個性能的增長量可能并不能反映一個復(fù)雜的應(yīng)用程序。

為了更多地提高性能,將 WebSphere servlet/JSP 結(jié)果緩存與 WebSphere 插件 ESI Fragment 處理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) 和 Edge Server 緩存功能集成在一起。對于繁重的基于讀取的工作負荷,通過使用這些功能可以得到許多額外的好處。

12. 為了提高程序員的工作效率,將 CMP 實體 bean 作為 O/R 映射的首選解決方案.

通過 WebSphere 框架(readahead、緩存、隔離級別等)優(yōu)化性能。如果可能,有選擇的應(yīng)用一些模式來達到提高性能的目的,例如 Fast-Lane 閱讀器 [Marinescu]。

對象/關(guān)系(O/R)映射是使用 Java 創(chuàng)建企業(yè)級的應(yīng)用程序的基礎(chǔ)。幾乎每個 J2EE 應(yīng)用程序都需要一些類型的 O/R 映射。J2EE 廠商提供一種 O/R 映射機制,這種機制在不同的廠商間是可移植的,高效的,并且能夠被一些標準及工具很好地支持。這就是 EJB 規(guī)范中的 CMP(容器管理的持久性)部分。

早期的 CMP 實現(xiàn)以表現(xiàn)不佳及不支持許多 SQL 結(jié)構(gòu)而著稱。然而,隨著 EJB 2.0 及 2.1 規(guī)范的出現(xiàn),以及被一些廠商所采納,并且隨著像 IBM WebSphere Studio Application Developer 的出現(xiàn),這些問題已經(jīng)不再是問題了。

CMP EJB 組件現(xiàn)在已經(jīng)被廣泛地應(yīng)用于許多高性能的應(yīng)用程序中。WebSphere 包括一些優(yōu)化功能以提高 EJB 組件的性能,優(yōu)化功能包括:對生命周期的緩存和 read-ahead 能力。這兩者優(yōu)化功能都是配置時的選項,并且不需要對應(yīng)用程序進行修改或者影響可移植性。

處于緩存狀態(tài)的生命周期緩存 CMP 狀態(tài)數(shù)據(jù)并提供基于時間的無效性。從處于緩存狀態(tài)的生命周期得到的性能提高可以達到選項 A 的緩存性能,并且仍然可以為您的應(yīng)用程序提供可伸展性。Read-ahead 能力和容器管理的關(guān)系結(jié)合使用。這個特性通過在相同的查詢中隨意地檢索相關(guān)的數(shù)據(jù)作為父數(shù)據(jù)而減少與數(shù)據(jù)庫的交互。如果相關(guān)的數(shù)據(jù)要通過使用并發(fā)的查詢來訪問的話,這種方法可以得到性能的改進。[Gunther]提供了詳細的描述以及通過這些特性得到的性能提高的細節(jié)。

此外,為了完全優(yōu)化您的 EJB 組件,當(dāng)指定隔離級別時要特別注意。盡可能使用最低的隔離級別,并且仍然保持您的數(shù)據(jù)的完整性。較低的隔離級別可以提供最佳的性能,并且可以降低出現(xiàn)數(shù)據(jù)庫死鎖的危險。

這是目前最有爭議的最佳實踐。已經(jīng)有大量的文章贊揚 CMP EJB,同樣的貶斥聲也不絕于耳。然而,這里最基本的問題是數(shù)據(jù)庫開發(fā)是困難的。當(dāng)您開始使用任何持久性解決方案之前,您需要掌握查詢以及數(shù)據(jù)庫鎖定如何工作這些基礎(chǔ)知識。如果您選擇使用 CMP EJB,您要確保您已經(jīng)通過一些書籍(例如 [Brown] 和 [Barcia])知道如何使用它們。在鎖定及爭用方面有一些微妙的交互難以理解,但是,在您耗費一定的時間及努力后會將其掌握的。

向AI問一下細節(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