最重要的 12個 J2EE 最佳實踐
最重要的 12個 J2EE 最佳實踐 收藏
最佳實踐
1、始終使用 MVC 框架。
2、在每一層都應用自動單元測試和測試管理。
3、按照規範來進行開發,而不是按照應用伺服器來進行開發。
4、從一開始就計劃使用 J2EE 安全性。
5、建立您所知道的。
6、當使用 EJB 元件時,始終使用會話 Facades。
7、使用無狀態會話 bean,而不是有狀態會話 bean.
8、使用容器管理的事務。
9、將 JSP 作為表示層的首選。
10、當使用 HttpSession 時,儘量只將當前事務所需要的狀態儲存其中,其他內容不要儲存在 HttpSession 中。
11、在 WebSphere 中,啟動動態快取,並使用 WebSphere servlet 快取機制。
12、為了提高程式設計師的工作效率,將 CMP 實體 bean 作為 O/R 對映的首選解決方案。
1. 始終使用 MVC 框架。
MVC 框架可以將業務邏輯(Java beans 和 EJB 元件)、控制器邏輯(Servlets/Struts 動作)、表示層(JSP、XML/XSLT)清晰地分離開來。良好的分層可以帶來許多好處。
MVC 框架對於成功使用 J2EE 是如此重要,以致沒有其他最佳實踐可以與其相提並論。模型-檢視-控制器(MVC)是設計 J2EE 應用程式的基礎。MVC 將您的程式程式碼簡單地劃分下面幾個部分:
負責業務邏輯的程式碼(即模型——通常使用 EJB 或者普通的 Java 物件來實現)。
負責使用者介面顯示的程式碼(即檢視——通常通過 JSP 及標記庫來實現,有時也使用 XML 和 XSLT 來實現)。
負責應用程式流程的程式碼(即控制器——通常使用 Java Servlet 或像 Struts 控制器這樣的類來實現)。
如 果您不遵循基本的 MVC 框架,在開發過程中就會出現許多的問題。最常見的問題就是在檢視部分新增了太多的成分,例如,可能存在使用 JSP 標記來執行資料庫訪問,或者在 JSP 中進行應用程式的流程控制,這在小規模的應用程式中是比較常見的,但是,隨著後期的開發,這樣做將會帶來問題,因為 JSP 逐步變得越來越難以維護和除錯。
類似地,我們也經常看到將檢視層構建到業務邏輯的情況。例如,一個常見的問題就是將在構建檢視時使用的 XML 解析技術直接應用到業務層。業務層應該對業務物件——而不是繫結到檢視的特定資料表示進行操作。
然 而,只是具有合適的元件並不一定意味著可以使您的應用程式得到合適的分層。我們常常見到一些應用程式包含 servlet、JSP 和 EJB 元件所有這三項,然而,其主要的業務邏輯卻是在 servlet 層實現的,或者應用程式導航是在 JSP 中處理的。您必須進行嚴格的程式碼檢查並重構您的程式碼,以確保應用程式的業務邏輯只在模型層(Model layer)進行處理,應用程式導航只通過控制器層(Controller layer)進行處理,而您的檢視(Views)只是將傳遞過來的模型物件以 HTML 及 JavaScript 的形式表示出來。
2. 在應用程式的每一層都使用自動單元測試和測試管理。
不要只是測試您的圖形使用者介面(GUI)。分層的測試使測試及維護工作變得極其簡單。
在 過去的幾年中,在方法學領域有了相當大的革新,例如新出現的被稱為 Agile(例如 SCRUM [Schwaber] 和極限程式設計 [Beck1])的輕量級方法現在已經得到了很普遍的應用。幾乎所有的這些方法中的一個共同的特徵是它們都提倡使用自動的測試工具,這些工具可以幫助開發 人員用更少的時間進行迴歸測試 (regression testing),並可以幫助他們避免由於不充分的迴歸測試造成的錯誤,因此可以用來提高程式設計師的工作效率。實際上,還有一種被稱為 Test-First Development [Beck2] 的方法,這種方法甚至提倡在開發實際的程式碼之前就先編寫單元測試。然而,在您測試程式碼之前,您需要將程式碼分割成一些可測試的片斷。一個"大泥球"是難以測 試的,因為它不是隻實現一個簡單的易於識別的功能。如果您的每個程式碼片斷實現多個方面的功能,這樣的程式碼將難以保證其完全的正確性。
MVC 框架(以及 J2EE 中的 MVC 實現)的一個優點就是元素的元件化能夠(實際上,相當的簡單)對您的應用程式進行單元測試。因此,您可以方便地對實體 bean、會話 bean 以及 JSP 獨立編寫測試用例,而不必考慮其他的程式碼。現在有許多用於 J2EE 測試的框架和工具,這些框架及工具使得這一過程更加簡單。例如,JUnit(是一種由 junit.org 開發的開放原始碼工具)和 Cactus(由 Apache 開發的開放原始碼工具)對於測試 J2EE 元件都非常有用。[Hightower] 詳細探討了如何在 J2EE 中使用這些工具。
儘管所有這些詳述了怎樣徹底地測試您的應用程式,但是我們仍然看到一些人認為只要他們測試了 GUI(可能是基於 Web 的 GUI,或者是獨立的 Java 應用程式),則他們就全面地測試了整個應用程式。GUI 測試很難達到全面的測試,有以下幾種原因。首先,使用 GUI 測試很難徹底地測試到系統的每一條路徑,GUI 僅僅是影響系統的一種方式,可能存在後臺運算、指令碼和各種各樣的其他訪問點,這也需要進行測試。然而,它們通常並不具有 GUI。第二,GUI 級的測試是一種非常粗粒度的測試。這種測試只是在巨集觀水平上測試系統的行為。這意味著一旦發現存在問題,則與此問題相關的整個子系統都要進行檢查,這使得 找出 bug(缺陷)將是非常困難的事情。第三,GUI 測試通常只有在整個開發週期的後期才能很好地得到測試,這是因為只有這那個時候 GUI 才得到完整的定義。這意味著只有在後期才可能發現潛在的 bug。第四,一般的開發人員可能沒有自動的 GUI 測試工具。因此,當一個開發人員對程式碼進行更改時,沒有一種簡單的方法來重新測試受到影響的子系統。這實際上不利於進行良好的測試。如果開發人員具有自動 的程式碼級單元測試工具,開發人員就能夠很容易地執行這些工具以確保所做的更改不會破壞已經存在的功能。最後,如果新增了自動構建功能,則在自動構建過程中 新增一個自動的單元測試工具是非常容易的事情。當完成這些設定以後,整個系統就可以有規律地進行重建,並且迴歸測試幾乎不需要人的參與。
另 外,我們必須強調,使用 EJB 和 Web 服務進行分散式的、基於元件的開發使得測試單個的元件變得非常必要。如果沒有"GUI"需要測試,您就必須進行低階(lower-level)測試。最好 以這種方式開始測試,省得當您將分散式的元件或 Web 服務作為您的應用程式的一部分時,您不得不花費心思重新進行測試。
總之,通過使用自動的單元測試,能夠很快地發現系統的缺陷,並且也易於發現這些缺陷,使得測試工作變得更加系統化,因此整體的質量也得以提高。
3. 按照規範來進行開發,而不是按照應用伺服器來進行開發。
要將規範熟記於心,如果要背離規範,要經過慎密的考慮後才可以這樣做。這是因為當您背離規則的時候,您所做的事情往往並不是您應該做的事情。
當 您要背離 J2EE 可以允許您做的事情的時候,這很容易讓使您遭受不幸。我們發現有一些開發人員鑽研一些 J2EE 允許之外的東西,他們認為這樣做可以"稍微"改善J2EE的效能,而他們最終只會發現這樣做會引起嚴重的效能問題,或者在以後的移植(從一個廠商到另一個 廠商,或者是更常見的從一個版本到另一個版本)中會出現問題。實際上,這種移植問題是如此嚴重,以致 [Beaton] 將此原則稱為移植工作的基本最佳實踐。
現在有好幾個地方如果不直接使用 J2EE 提供的方法肯定會產生問題。一個常見的例子就是開發人員通過使用 JAAS 模組來替代 J2EE 安全性,而不是使用內建的遵循規範的應用程式伺服器機制來進行驗證和授權。要注意不要脫離 J2EE 規範提供的驗證機制,如果脫離了此規範,這將是系統存在安全漏洞以及廠商相容性問題的主要原因。類似地,要使用 servlet 和 EJB 規範提供的授權機制,並且如果您要偏離這些規範的話,要確保使用規範定義的 API(例如 getCallerPrincipal())作為實現的基礎。通過這種方式,您將能夠利用廠商提供的強安全性基礎設施,其中,業務要求需要支援複雜的授權 規則。
其他常見的問題包括使用不遵循 J2EE 規範的永續性機制(這使得事務管理變得困難)、在J2EE程式中使用不適當的J2SE 方法(例如執行緒或 singleton),以及使用您自己的方法解決程式到程式(program-to-program)的通訊,而不是使用 J2EE 內在支援的機制(例如 JCA、JMS 或 Web 服務)。當您將一個遵循 J2EE 的伺服器移植到其他的伺服器上,或者移植到相同伺服器的新版本上,上述的設計選擇將會造成無數的問題。唯一要背離規範的情況是,當一個問題在規範的範圍內 無法解決的時候。例如,安排執行定時的業務邏輯在 EJB2.1 出現之前是一個問題,在類似這樣的情況下,我們建議當有廠商提供的解決方案時就使用廠商提供的解決方案(例如 WebSphere Application Server Enterprise 中的 Scheduler 工具),而在沒有廠商提供的解決方案時就使用第三方提供的工具。如果使用廠商提供的解決方案,應用程式的維護以及將其移植到新的規範版本將是廠商的問題, 而不是您的問題。
最後,要注意不要太早地採用新技術。太過於熱衷採用還沒有整合到 J2EE 規範的其他部分或者還沒有整合到廠商的產品中的技術常會帶來災難性的後果。支援是關鍵的——如果您的廠商不直接支援一種特定的在 JSR 中提出的技術,但此技術還沒有被 J2EE 所接受,那麼您就不應該採用此技術。畢竟,我們中的大多數人從事解決業務問題,而不是推進技術的發展。
4. 從一開始就計劃使用 J2EE 安全性。
啟用 WebSphere 安全性。這使您的 EJB 和 URL 至少可以讓所有授權使用者訪問。不要問為什麼——照著做就是了。
在 與我們合作的客戶中,一開始就打算啟用 WebSphere J2EE 安全性的顧客是非常少的,這一點一直讓我們感到吃驚。據我們估計大約只有 50% 的顧客一開始就打算使用此特性。例如,我們曾與一些大型的金融機構(銀行、代理等等)合作過,他們也沒有打算啟用安全性。幸運的是,這種問題在部署之前的 檢查時就得以解決.
不使用 J2EE 安全性是危險的事情。假設您的應用程式需要安全性(幾乎所有的應用程式都需要),您敢打賭您的開發人員能夠構建出自己的安全性系統,而這個系統比您從 J2EE 廠商那裡買來的更好。這可不是個好的賭注,為分散式的應用程式提供安全性是異常困難的。例如,您需要使用網路安全加密令牌控制對 EJB 的訪問。以我們的經驗看來,大多數自己構建的安全性系統是不安全的,並且有重大的缺陷,這使產品系統極其脆弱。
一些不使用 J2EE 安全性的理由包括:擔心效能的下降,相信其他的安全性(例如 Netegrity SiteMinder)可以取代 J2EE 安全性,或者是不知道 WebSphere Application Server 安全特性及功能。不要陷入這些陷阱之中,尤其是,儘管像 Netegrity SiteMinder 這樣的產品能夠提供優秀的安全特性,但是僅僅其自身不可能保護整個 J2EE 應用程式。這些產品必須與 J2EE 應用程式伺服器聯合起來才可能全面地保護您的系統。
其他的一種常見的不使用 J2EE 安全性的原因是:基於角色的模型沒有提供足夠的粒度訪問控制以滿足複雜的業務規則。儘管事實是這樣的,但這也不應該成為不使用 J2EE 安全性的理由。相反地,應該將 J2EE 驗證及 J2EE 角色與特定的擴充套件規則結合起來。如果複雜的業務規則需要做出安全性決策,那就編寫相應的程式碼,其安全性決策要基於可以直接使用的以及可靠的 J2EE 驗證資訊(使用者 ID 和角色)。
5. 建立您所知道的。
反覆的開發工作將使您能夠逐漸地掌握所有的 J2EE 模組。要從建立小而簡單的模組開始而不是從一開始就馬上涉及到所有的模組。
我們必須承認 J2EE 是龐大的體系。如果一個開發小組只是開始使用 J2EE,這將很難一下子就能掌握它。在 J2EE 中有太多的概念和 API 需要掌握。在這種情況下,成功掌握 J2EE 的關鍵是從簡單的步驟開始做起。
這 種方法可以通過在您的應用程式中建立小而簡單的模組來得到最好的實現。如果一個開發小組通過建立一個簡單的域模型以及後端的永續性機制(也許使用的是 JDBC),並且對其進行了完整的測試,這會增強他們的自信心,於是他們會使用該域模型去掌握使用 servlet 和 JSP 的前端開發。如果一個開發組發現有必要使用 EJB,他們也會類似地開始在容器管理的永續性 EJB 元件之上使用簡單的會話 Facades,或者使用基於 JDBC 的資料訪問物件(JDBC-based Data Access Objects,DAO),而不是跳過這些去使用更加複雜的構造(例如訊息驅動bean和JMS)。
這種方法並不是什麼新方法,但是 很少有開發組以這種方式來培養他們的技能。相反地,多數開發組由於嘗試馬上就構建所有的模組,同時涉及 MVC 中的檢視層、模型層和控制器層,這樣做的結果是他們往往會陷入進度的壓力之中。他們應該考慮一些敏捷(Agile)開發方法,例如極限程式設計(XP),這種 開發方法採用一種增量學習及開發方法。在 XP 中有一種稱為 ModelFirst 的過程,這個過程涉及到首先構建域模型作為一種機制來組織和實現使用者場景。基本說來,您要構建域模型作為您要實現的使用者場景的首要部分,然後在域模型之上 構建一個使用者介面(UI)作為使用者場景實現的結果。這種方法非常適合讓一個開發組一次只學到一種技術,而不是讓他們同時面對很多種情況(或者讓他們讀很多 書),這會令他們崩潰的。
還有,對每個應用程式層重複的開發可能會包含一些適當的模式及最佳實踐。如果您從應用程式的底層開始應用一些模式如資料訪問物件和會話 Facades,您就不應該在您的JSP和其他檢視物件中使用域邏輯。
最後,當您開發一些簡單的模組時,在開始的初期就可以對您的應用程式進行效能測試。如果直到應用程式開發的後期才進行效能測試的話,這往往會出現災難性的後果。
6. 當使用 EJB 元件時,始終使用會話 Facades。
決不要將實體 bean 直接暴露給任何使用者型別。對實體 bean 只可以使用本地 EJB 介面(Local EJB interfaces)。
當 使用 EJB 元件時,使用一個會話 Facades 是一個確認無疑的最佳實踐。實際上,這個通用的實踐被廣泛地應用到任何分散式的技術中,包括 CORBA、EJB 和 DCOM。從根本上講,您的應用程式的分佈"交叉區域"越是底層化,對小塊的資料由於多次重複的網路中繼造成的時間消耗就越少。要達到這個目的的方法就 是:建立大粒度的 Facades 物件,這個物件包含邏輯子系統,因而可以通過一個方法呼叫就可以完成一些有用的業務功能。這種方法不但能夠降低網路開銷,而且在 EJB 內部通過為整個業務功能建立一個事務環境也可以大大地減少對資料庫的訪問次數。
EJB 本地介面(從 EJB 2.0 規範開始使用)為共存的 EJB 提供了效能優化方法。本地介面必須被您的應用程式顯式地進行訪問,這需要程式碼的改變和防止以後配置 EJB 時需要應用程式的改變。由於會話 Facades 和它包含的整個 EJB 對於彼此來說都應該是本地的,我們建議對會話 Facades 後面的實體 bean 使用本地介面。然而,會話 Facades 本身的實現(典型例子如無狀態會話 bean)應該設計為遠端介面。
為了效能 的優化,可以將一個本地介面新增到會話 Facades。這樣做利用了這樣一個事實:在大多數情況下(至少在 Web 應用程式中),您的 EJB 客戶端和 EJB 會共同存在於同一個 Java 虛擬機器(JVM)中。另外一種情況,如果會話 Facades 在本地被呼叫,可以使用 J2EE 應用伺服器配置優化(configuration optimizations),例如 WebSphere 中的"No Local Copies"。然而,您必須注意到這些可供選擇的方案會將互動方法從按值傳遞(pass-by-value)改變為按引用傳遞(pass-by- reference)。這可能會在您的程式碼中產生很微妙的錯誤。當您要利用這些方案時,您應該在一開始就考慮其可行性。
如果在您的會 話 Facades 中使用遠端介面(而不是本地介面),您也可以將同樣的會話 Facades 在 J2EE 1.4 中以相容的方式作為 Web 服務來配置。這是因為 JSR 109(J2EE 1.4 中的 Web 服務部署部分)要求使用無狀態會話 bean 的遠端介面作為 EJB Web 服務和 EJB 實現的介面。這樣做是值得的,因為這樣做可以為您的業務邏輯增加客戶端型別的數量。
7. 使用無狀態會話 bean,而不是有狀態會話 bean。
這樣做可以使您的系統經得起錯誤的終止。使用 HttpSession 儲存和使用者相關的狀態。
以 我們的觀點看來,有狀態會話 bean 的概念已經過時了。如果您仔細對其考慮一下,一個有狀態會話 bean 實際上與一個 CORBA 物件在體系結構上是完全相同的,無非就是一個物件例項,繫結到一個伺服器,並且依賴於伺服器來管理其生命週期。如果伺服器關閉了,這種物件也就不存在,那 麼這個 bean 的客戶端的資訊也就不存在。
J2EE 應用伺服器為有狀態會話 bean 提供的故障轉移(failover)能夠解決一些問題,但是有狀態的解決方案沒有無狀態的解決方案易於擴充套件。例如,在 WebSphere Application Server 中,對無狀態會話 bean 的請求,是通過對部署無狀態會話的成員叢集進行平衡載入來實現。相反地,J2EE 應用伺服器不能對有狀態 bean 的請求進行平衡載入。這意味著您的叢集中的伺服器的載入過程會是不均衡的。此外,使用有狀態會話 bean 將會再新增一些狀態到您的應用伺服器上,這也是不好的做法。這樣就增加了系統的複雜性,並且在出現故障的情況下使問題變得複雜化。建立健壯的分散式系統的 一個關鍵原則是儘量使用無狀態行為。
因此,我們建議對大多數應用程式使用無狀態會話 bean 方法。任何在處理時需要使用的與使用者相關的狀態應該以引數的形式傳送到 EJB 的方法中(並且通過使用一種機制如 HttpSession 來儲存它)或者從永續性的後端儲存(例如通過使用實體 bean)作為 EJB 事務的一部分來進行檢索。在合適的情況下,這個資訊可以快取到記憶體中,但是要注意在分散式的環境中儲存這種快取所潛在的挑戰性。快取非常適合於只讀資料。
總之,您要確保從一開始就要考慮到可伸展性。檢查設計中的所有設想,並且考慮到當您的應用程式要在多個伺服器上執行時,是否也可以正常執行。這個規則不但適合上述情況的應用程式程式碼,也適用於如 MBean 和其他管理介面的情況下。
避免使用有狀態性不只是對 IBM/WebSphere 的建議,這是一個基本的 J2EE 設計原則。
8. 使用容器管理的事務。
學習一下 J2EE 中的兩階段提交事務,並且使用這種方式,而不是開放您自己的事務管理。容器在事務優化方面幾乎總是比較好的。
使用容器管理的事務(CMT)提供了兩個關鍵的優勢(如果沒有容器支援這幾乎是不可能的):可組合的工作單元和健壯的事務行為。
如 果您的應用程式程式碼顯式地使用了開始和結束事務(也許使用 javax.jts.UserTransaction 或者甚至是本地資源事務),而將來的要求需要組合模組(也許會是程式碼重構的一部分),這種情況下往往需要改變事務程式碼。例如,如果模組 A 開始了一個資料庫事務,更新資料庫,隨後提交事務,並且有模組 B 做出同樣的處理,請考慮一下當您在模組 C 中嘗試使用上述兩個模組,會出現什麼情況呢?現在,模組 C 正在執行一個邏輯動作,而這個動作實際上將呼叫兩個獨立的事務。如果模組 B 在執行中失敗了,而模組 A 的事務仍然能被提交。這是我們所不希望出現的行為。如果,相反地,模組 A 和模組 B 都使用 CMT 的話,模組 C 也可以開始一個 CMT(通常通過配置描述符),並且在模組 A 和模組 B 中的事務將是同一個事務的隱含部分,這樣就不再需要複雜的重寫程式碼的工作了。
如果您的應用程式在同一個操作中需要訪問多種資源,您就 要使用兩階段提交事務。例如,如果從 JMS 佇列中刪除一個訊息,並且隨後更新基於這條訊息的紀錄,這時,要保證這兩個操作都會執行或都不會執行就變得尤為重要。如果一條訊息已經從佇列中被刪除,而 系統沒有更新與此訊息相關的資料庫中的紀錄,那麼這種系統是不穩定的。一些嚴重的客戶及商業糾紛源自不一致的狀態。
我們時常看到一些 客戶應用程式試圖實現他們自己的解決方案。也許會通過應用程式的程式碼在資料庫更新失敗的時候 "撤銷"對佇列的操作。我們不提倡這樣做。這種實現要比您最初的想象要複雜得多,並且還有許多其他的情況(想象一下如果應用程式在執行此操作的過程中突然 崩潰的情況)。作為替代的方式,應該使用兩階段提交事務。如果您使用 CMT,並且在一個單一的 CMT 中訪問兩階段提交的資源(例如 JMS 和大多數資料庫),WebSphere 將會處理所有的複雜工作。它將確保整個事務被執行或者都不被執行,包括系統崩潰、資料庫崩潰或其他的情況。其實現在事務日誌中儲存著事務狀態。當應用程式 訪問多種資源的時候,我們怎麼強調使用 CMT 事務的必要性都不為過。
9. 將 JSP 作為表示層的首選。
只有在需要多種表示輸出型別,並且輸出型別被一個單一的控制器及後端支援時才使用 XML/XSLT。
我 們常聽到一些爭論說,為什麼您選擇 XML/XSLT 而不是 JSP 作為表示層技術。選擇 XML/XSLT 的人的觀點是,JSP" 允許您將模型和檢視混合在一起",而 XML/XSLT 不會有這種問題。遺憾的是,這種觀點並不完全正確,或者至少不像白與黑那樣分的清楚。實際上,XSL 和 XPath 是程式語言。XSL 是圖靈完成的(Turing-complete),儘管它不符合大多數人定義的程式語言,因為它是基於規則的,並且不具備程式設計師習慣的控制工具。
現 在的問題是既然給予了這種靈活性,開發人員就會利用這種靈活性。儘管每個人都認同 JSP 使開發人員容易在檢視中加入"類似模型"的行為,而實際上,在 XSL 中也有可能做出一些同樣的事情。儘管從 XSL 中進行訪問資料庫這樣的事情會非常困難,但是我們曾經見到過一些異常複雜的 XSLT 樣式表執行復雜的轉換,這實際上是模型程式碼。
然 而,應該選擇 JSP 作為首選的表示技術的最基本的原因是,JSP 是現在支援最廣泛的、也是最被廣泛理解的 J2EE 檢視技術。而隨著自定義標記庫、JSTL 和 JSP2.0 的新特性的引入,建立 JSP 變得更加容易,並且不需要任何 Java 程式碼,以及可以將模型和檢視清晰的分離開。在一些開發環境中(如 WebSphere Studio)加入了對 JSP(包括對除錯的支援)的強大支援,並且許多開發人員發現使用 JSP 進行開發要比使用 XLS 簡單,一些支援 JSP 的圖形設計工具及其他特徵(尤其在 JSF 這樣的框架下)使得開發人員可以以所見即所得的方式進行 JSP 的開發,而對於 XSL 有時不容易做到。
最後一個要謹慎考慮使用 JSP 的原因是速度問題。在 IBM 所作的對比 XSL 和 JSP 相對速度的效能測試顯示:在大多數情況下,JSP 在生成同樣的 HTML 的時候,要比 XSL 快好幾倍,甚至使用編譯過的 XSL 也是如此。儘管多數情況下這不是問題,但在效能要求很高的情況下,這就會成為問題。
然而,這也不能說,您永遠也不要使用 XSL。在一些情況下,XSL 能夠表示一組固定的資料,並且可以基於不同的樣式表來以不同的方式顯示這些資料的能力是顯示檢視的最佳解決方案。然而,這只是一種例外的情況,而不是通用 的規則。如果您只是生成 HTML 來表達每一個頁面,那麼在大多數情況下,XSL 是一種不必要的技術,並且,它給您的開發人員所帶來的問題遠比它所能解決的問題多。
10. 當使用 HttpSession 時,儘量只將當前事務所需要的狀態儲存其中,其他內容不要儲存在 HttpSession 中。
啟用會話永續性。
HttpSessions 對於儲存應用程式狀態資訊是非常有用的。其 API 易於使用和理解。遺憾的是,開發人員常常遺忘了 HttpSession 的目的——用來保持暫時的使用者狀態。它不是任意的資料快取。我們已經見到過太多的系統為每個使用者的會話放入了大量的資料(達到兆位元組)。那好了,如果同時 有 1000 個登入系統的使用者,每個使用者擁有 1MB 的會話資料,那麼就需要 1G 或者更多的記憶體用於這些會話。要使這些 HTTP 會話資料較小一些,不然的話,您的應用程式的效能將會下降。一個大約比較合適的資料量應該是每個使用者的會話資料在 2K-4K 之間,這不是一個硬性的規則,8K 仍然沒有問題,但是顯然會比 2K 時的速度要慢。一定要注意,不要使 HttpSession 變成資料堆積的場所。
一個常見的問題是使用 HttpSession 快取一些很容易再建立的資訊,如果有必要的話。由於會話是永續性的,進行不必要的序列化以及寫入資料是一種很奢侈的決定。相反地,應該使用記憶體中的雜湊表 來快取資料,並且在會話中儲存一個對此資料進行引用的關鍵字。這樣,如果不能成功登入到另外的應用伺服器的話,就可以重新建立資料。
當 談及會話永續性時,不要忘記要啟用這項功能。如果您沒有啟用會話永續性,或者伺服器因為某種原因停止了(伺服器故障或正常的維護),則所有此應用服務的當 前使用者的會話將會丟失。這是件令人非常不高興的事情。使用者不得不重新登入,並且重新做一些他們曾經已經做過的事情。相反地,如果啟用了會話永續性, WebSphere 會自動將使用者(以及他們的會話)移到另外一個應用伺服器上去。使用者甚至不知道會有這種事情的發生。我們曾經見到過一些產品系統因為存在於原生程式碼中令人難 以忍受的 bug(不是 IBM 的程式碼!)而突然崩潰的情況,這這種情況下,上述功能仍然可以執行良好。
11. 在 WebSphere 中,使用動態快取,並使用 WebSphere servlet 快取機制.
通過使用這些功能,系統效能可以得到很大的提高,而開銷是很小的。並且不影響程式設計模型。
通 過快取來提高效能的好處是眾所周知的事情。遺憾的是,當前的 J2EE 規範沒有包括一種用於 servlet/JSP 快取的機制。然而,WebSphere 提供了對頁面以及片斷快取的支援,這種支援是通過其動態快取功能來實現的,並且不需要對應用程式作出任何改變。其快取的策略是宣告性的,而且其配置是通過 XML 配置描述符來實現的。因此,您的應用程式不會受到影響,並保持與 J2EE 規範的相容性和移植性,同時還從 WebSphere 的 servlet 及 JSP 的快取機制中得到效能的優化。
從 servet 及 JSP 的動態快取機制得到的效能的提高是顯而易見的,這取決於應用程式的特性。Cox 和 Martin [Cox] 指出對一個現有的 RDF(資源描述格式)站點摘要 (RSS)servlet,當使用動態快取時,其效能可以提高 10%。請注意這個實驗只涉及到一個簡單的 servlet,這個效能的增長量可能並不能反映一個複雜的應用程式。
為了更多地提高效能,將 WebSphere servlet/JSP 結果快取與 WebSphere 外掛 ESI Fragment 處理器、IBM HTTP Server Fast Response Cache Accelerator (FRCA) 和 Edge Server 快取功能整合在一起。對於繁重的基於讀取的工作負荷,通過使用這些功能可以得到許多額外的好處。
12. 為了提高程式設計師的工作效率,將 CMP 實體 bean 作為 O/R 對映的首選解決方案.
通過 WebSphere 框架(readahead、快取、隔離級別等)優化效能。如果可能,有選擇的應用一些模式來達到提高效能的目的,例如 Fast-Lane 閱讀器 [Marinescu]。
對 象/關係(O/R)對映是使用 Java 建立企業級的應用程式的基礎。幾乎每個 J2EE 應用程式都需要一些型別的 O/R 對映。J2EE 廠商提供一種 O/R 對映機制,這種機制在不同的廠商間是可移植的,高效的,並且能夠被一些標準及工具很好地支援。這就是 EJB 規範中的 CMP(容器管理的永續性)部分。
早期的 CMP 實現以表現不佳及不支援許多 SQL 結構而著稱。然而,隨著 EJB 2.0 及 2.1 規範的出現,以及被一些廠商所採納,並且隨著像 IBM WebSphere Studio Application Developer 的出現,這些問題已經不再是問題了。
CMP EJB 元件現在已經被廣泛地應用於許多高效能的應用程式中。WebSphere 包括一些優化功能以提高 EJB 元件的效能,優化功能包括:對生命週期的快取和 read-ahead 能力。這兩者優化功能都是配置時的選項,並且不需要對應用程式進行修改或者影響可移植性。
處於快取狀態的生命週期快取 CMP 狀態資料並提供基於時間的無效性。從處於快取狀態的生命週期得到的效能提高可以達到選項 A 的快取效能,並且仍然可以為您的應用程式提供可伸展性。Read-ahead 能力和容器管理的關係結合使用。這個特性通過在相同的查詢中隨意地檢索相關的資料作為父資料而減少與資料庫的互動。如果相關的資料要通過使用併發的查詢來 訪問的話,這種方法可以得到效能的改進。[Gunther]提供了詳細的描述以及通過這些特性得到的效能提高的細節。
此外,為了完全優化您的 EJB 元件,當指定隔離級別時要特別注意。儘可能使用最低的隔離級別,並且仍然保持您的資料的完整性。較低的隔離級別可以提供最佳的效能,並且可以降低出現資料庫死鎖的危險。
這 是目前最有爭議的最佳實踐。已經有大量的文章讚揚 CMP EJB,同樣的貶斥聲也不絕於耳。然而,這裡最基本的問題是資料庫開發是困難的。當您開始使用任何永續性解決方案之前,您需要掌握查詢以及資料庫鎖定如何 工作這些基礎知識。如果您選擇使用 CMP EJB,您要確保您已經通過一些書籍(例如 [Brown] 和 [Barcia])知道如何使用它們。在鎖定及爭用方面有一些微妙的互動難以理解,但是,在您耗費一定的時間及努力後會將其掌握的。
結束語
在這個簡短的摘要中,我們已經向您介紹了 J2EE 中的核心模式和最佳實踐,這使得 J2EE 開發成為一種可管理的過程。儘管我們並沒有給出所有在實踐中使用這些模式的必要細節,但是我們希望能夠給您足夠的指點和指導,以幫助您決定下一步要做什麼。
作者簡介
Kyle Brown 是 IBM Software Services for WebSphere 的高階技術成員。Kyle 向財富 500 強客戶提供關於物件導向主題和 J2EE 技術的諮詢服務、培訓和指導。他與別人合著了 Enterprise Java Programming with IBM WebSphere、WebSphere AEs 4.0 Workbook for Enterprise Java Beans(第 3 版)和 The Design Patterns Smalltalk Companion。他還經常在研討會上發表關於企業 Java、OO 設計和設計模式的演講。
Keys Botzum 是 IBM Software Services for WebSphere 的高階顧問。他在大規模分散式系統設計方面有十多年經驗,並且專攻安全性問題。Keys 使用過各種分散式技術,包括 Sun RPC、DCE、CORBA、AFS 和 DFS。最近,他著重研究 J2EE 及其相關技術。他擁有史丹佛大學電腦科學碩士學位和卡內基梅隆大學應用數學/電腦科學學士學位。
Ruth Willenborg 是 WebSphere Application Server Performance 組的經理。她與人合著了 Performance Analysis for Java Web Sites(Addison-Wesley,2002 年)一書。
本文來自CSDN部落格,轉載請標明出處:http://blog.csdn.net/shadowkiss/archive/2007/02/25/1513878.aspx
相關文章
- 12個最重要的J2EE最佳實踐
- J2EE架構的6個最佳實踐架構
- Apache Kafka 12個最佳實踐ApacheKafka
- J2EE架構學習者的6個最佳實踐架構
- 《J2EE 最佳實踐》作者訪談錄
- Google:12 條 Golang 最佳實踐Golang
- WebGPU 的幾個最佳實踐WebGPU
- 十個JDBC的最佳實踐JDBC
- Go 語言 12 條最佳實踐Go
- 使用GitHub的十個最佳實踐Github
- 24個javascript最佳實踐JavaScript
- 7 個 jQuery 最佳實踐jQuery
- webService幾個最佳實踐Web
- 8個雲成本最佳化的最佳實踐
- 有效的微服務:10 個最佳實踐微服務
- 有效尋源的4個最佳實踐
- 7個API安全最佳實踐API
- 20 個 OpenSSH 最佳安全實踐
- AI質檢最佳化實踐:召回率和準確率,哪個更重要?AI
- 測試微服務的4個最佳實踐微服務
- 13 個設計 REST API 的最佳實踐RESTAPI
- 10個精妙的Java編碼最佳實踐Java
- 成功遠端開發者的七個最佳實踐
- 20個異常處理的最佳實踐
- 5個async/await最佳實踐AI
- 10個專案文件最佳實踐
- 10 個專案文件最佳實踐
- [譯]使用者賬戶、授權和密碼管理的 12 個最佳實踐密碼
- RocketMQ的最佳實踐MQ
- mysqldump的最佳實踐MySql
- memcache的最佳實踐
- Java 的最佳實踐Java
- Kubernetes日誌的6個最佳實踐
- 處理Java異常的9個最佳實踐Java
- 17 個提高效能的 Flutter 最佳實踐Flutter
- Laravel 你應該知道的幾個最佳實踐Laravel
- Java程式設計師的八個最佳實踐Java程式設計師
- Java異常處理的9個最佳實踐Java