12個最重要的J2EE最佳實踐

12個最重要的J2EE最佳實踐

 

1. 始終使用 MVC 框架。
MVC
框架可以將業務邏輯(Java beans EJB 組件)、控制器邏輯(Servlets/Struts 動作)、表示層(JSPXML/XSLT)清晰地分離開來。良好的分層可以帶來許多好處。
MVC
框架對於成功使用 J2EE 是如此重要,以致沒有其他最佳實踐可以與其相提並論。模型-視圖-控制器(MVC)是設計 J2EE 應用程序的基礎。MVC 將您的程序代碼簡單地劃分下面幾個部分:
負責業務邏輯的代碼(即模型??通常使用 EJB 或者普通的 Java 對象來實現)。
負責用戶界面顯示的代碼(即視圖??通常通過 JSP 及標記庫來實現,有時也使用 XML XSLT 來實現)。
負責應用程序流程的代碼(即控制器??通常使用 Java Servlet 或像 Struts 控制器這樣的類來實現)。
如 果您不遵循基本的 MVC 框架,在開發過程中就會出現許多的問題。最常見的問題就是在視圖部分添加了太多的成分,例如,可能存在使用 JSP 標記來執行數據庫訪問,或者在 JSP 中進行應用程序的流程控制,這在小規模的應用程序中是比較常見的,但是,隨着後期的開發,這樣做將會帶來問題,因爲 JSP 逐步變得越來越難以維護和調試。
類似地,我們也經常看到將視圖層構建到業務邏輯的情況。例如,一個常見的問題就是將在構建視圖時使用的 XML 解析技術直接應用到業務層。業務層應該對業務對象??而不是綁定到視圖的特定數據表示進行操作。
然 而,只是具有合適的組件並不一定意味着可以使您的應用程序得到合適的分層。我們常常見到一些應用程序包含 servletJSP 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 內在支持的機制(例如 JCAJMS 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 ObjectsDAO),而不是跳過這些去使用更加複雜的構造(例如消息驅動beanJMS)。
這種方法並不是什麼新方法,但是很少有開 發組以這種方式來培養他們的技能。相反地,多數開發組由於嘗試馬上就構建所有的模塊,同時涉及 MVC 中的視圖層、模型層和控制器層,這樣做的結果是他們往往會陷入進度的壓力之中。他們應該考慮一些敏捷(Agile)開發方法,例如極限編程(XP),這種 開發方法採用一種增量學習及開發方法。在 XP 中有一種稱爲 ModelFirst 的過程,這個過程涉及到首先構建域模型作爲一種機制來組織和實現用戶場景。基本說來,您要構建域模型作爲您要實現的用戶場景的首要部分,然後在域模型之上 構建一個用戶界面(UI)作爲用戶場景實現的結果。這種方法非常適合讓一個開發組一次只學到一種技術,而不是讓他們同時面對很多種情況(或者讓他們讀很多 書),這會令他們崩潰的。
還有,對每個應用程序層重複的開發可能會包含一些適當的模式及最佳實踐。如果您從應用程序的底層開始應用一些模式如數據訪問對象和會話 Facades,您就不應該在您的JSP和其他視圖對象中使用域邏輯。
最後,當您開發一些簡單的模塊時,在開始的初期就可以對您的應用程序進行性能測試。如果直到應用程序開發的後期才進行性能測試的話,這往往會出現災難性的後果。

6. 當使用 EJB 組件時,始終使用會話 Facades

決不要將實體 bean 直接暴露給任何用戶類型。對實體 bean 只可以使用本地 EJB 接口(Local EJB interfaces)。
當 使用 EJB 組件時,使用一個會話 Facades 是一個確認無疑的最佳實踐。實際上,這個通用的實踐被廣泛地應用到任何分佈式的技術中,包括 CORBAEJB 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 109J2EE 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])知道如何使用它們。在鎖定及爭用方面有一些微妙的交互難以理解,但是,在您耗費一定的時間及努力後會將其掌握的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章