· JMS 1.02 標準擴展 API
J2EE 應用組件可以使用消息傳遞資源與其它企業應用異步通信。JMS 1.02 標準擴展 API 提供獨立于供應商的方式來與消息傳遞服務供應商通信。與數據庫資源一樣,通過使用可以合用的連接對象來訪問消息隊列。
JMS 1.02 API 包括下列接口以支持資源合用:
JMS 服務供應商實現那些接口。 代碼樣本 顯示了 EJB 組件如何使用連接對象來訪問消息隊列資源。
在連接合用時,JMS factory 類通常要有代理(由管理員配置),以便 open() 和 close() 請求實際上發往管理連接池的代理。遵循 JMS API 的指示,JMS 服務器供應商可以實現數據庫來管理消息隊列。在那種情況下,適當的 JDBC 驅動程序將提供連接合用。如果應用已經使用 JDBC 2.0 連接池啟用的數據庫,那么,您所要做的只是為 JMS 配置 JNDI 特性,以使用那個 JDBC 實例。
· JNDI API for LDAP
javax.naming.LDAP 包包括特定于 LDAP 的類(而不包括在通用 javax.naming.directory 中)。與 JDBC 2.0 和 JMS 1.02 API 不同,JNDI LDAP API 不為連接合用指定任何接口。目錄服務供應商可以有選擇地通過 SDK 提供支持。例如,iPlanet 的 Netscape Directory Server SDK 4.0 for Java 包括以下構建 LDAP 客戶機所用的類:
CCCCCC">public class netscape.ldap.util.ConnectionPool extends java.lang.Object methods: Connection(), getConnection(), close(), etc. |
有關詳細信息,請參閱 "Netscape Directory Server Application Programmer's Guide" 。
· J2EE Connector Architecture 1.0
在以上所有示例中,EJB 組件必須導入特定于供應商的實現類,以使用資源的連接合用設施。很明顯,這種做法降低了 EJB 的可移植性,并不利于 J2EE 的發展。
理想的做法是內置一個可用于任何資源類型和所有連接管理功能(包括合用)的通用連接接口。這就是即將出現的 J2EE Connector Architecture 1.0 規范的目標之一,在我寫這篇文章之時,就已經公開了一份草案副本。(請參閱 參考資料 )。
圖 3 顯示了體系結構內部的主要概念, 資源適配器 。應用服務器所支持的每一種資源類型的可插入組件,資源適配器,都在應用服務器地址空間中執行。訪問那些適配器的客戶機 API 可以是 Common Client Interface (CCI) 或(為了向后兼容)特定于資源的 API(例如 JDBC 2.0)。例如,CCI 定義 javax.resource.clearcase/" target="_blank" >cci.ConnectionFactory 和 javax.resource.cci.Connection ,分別作為連接 factory 和連接的接口 -- 與上一節中提到的 JDBC 2.0 接口類似。
圖 3. J2EE Connector Architecture 1.0 中的資源適配器
Connector 1.0 中的連接合用
Connector 1.0 的編程模型如下:
在那種情況下,假定資源適配器供應商實現接口。然而,連接器體系結構并不指定應用服務器如何實現連接池,而是提供一些指示,例如,根據適配器類型、服務質量 (QoS) 需求等來劃分連接池。有關詳細信息,請參閱 J2EE Connector Architecture 規范 。
例如,基于即將出現的 EJB 2.0 連接器體系結構的、至企業/舊有系統的 Sun 連接器的產品版 iPlanet Unified Integration Framework Toolkit v 6.0,為 EJB 層可能要訪問的每個后端系統定義了連接池。一個定期執行的線程監控池對象的使用和壽命。有關詳細信息,請參閱 iPlanet Unified Integration Framewor 。
· EJB 層的設計考慮事項
盡管有了管理連接池的資源管理器,但是還不能保證 EJB 層具有最優性能 -- 還有一些設計考慮事項!
首先,考慮以下 EJB 客戶機代碼示例,該客戶機訪問實現連接池的 LDAP 目錄 。
import netscape.ldap.util.*; ... public class NewCustomerBean implements SessionBean { ... private SessionContext context; // Bean Context private LDAPConnection lc; // LDAP Connection object ... public void setSessionContext(SessionContext sc) { this.context = sc; // initialize JNDI lookup parameters Context ctx = new InitialContext(parms); ... ConnectionPool cp = (ConnectionPool)ctx.lookup(cpsource); // Establish LDAP Connection. try { this.lc = cp.getConnection(); ... } |
以上做法有什么不妥嗎?首先,有狀態會話對象 ( NewCustomerBean ) 在 setEntityContext 中打開連接對象,然后持續占用它,直到使用完為止 -- 如果用戶(會話)數量迅速增加,就成為代價相當大的實現。第二,也是更重要的,因為連接對象不是序列化的,所以,按照 EJB 1.2 規范,容器可以在鈍化時(例如,將會話 bean 從其活動狀態移至 bean 實例池)廢棄 bean 實例。
一種替代方法是分別在會話 bean 的 ejbActivate() 和 ejbPassivate() 方法中獲取和釋放資源連接。如果沒有連接池,代價當然會很高,也不會建議那樣做。然而,有了合用之后,使用該技術,可以用最小的 EJB 層開銷來獲取和釋放連接。這里的要點在于:除了規范和實現所提供的設施之外,設計選擇總是關鍵性能決定因素。
第二個考慮事項是有關認證問題的。您可能已經注意到,合用的連接意味著共享的連接,而共享的連接意味著連接不與特定的認證證書綁定。例如,在 JDBC 2.0 連接中,應用服務器池管理器在啟動時,使用一個存儲在配置文件中的認證證書(通常是用戶標識/口令)來從數據庫管理器請求預設數量的連接。有時候,那可能不滿足應用的安全性策略。LDAP 連接需要將 LDAP 子樹與特定證書綁定,因而也有同樣的問題。在那些情況下,一種替代方法可能是使用利用特定證書建立好的已高速緩存的連接,它可以對相同類型的證書重復使用。這種方法的不利之處是已高速緩存的連接要保留很長時間。另一種替代方法可能是對資源使用通用連接,并實現某種應用層安全性。
· 結束語
在本文中,我根據資源的共享特性和訪問資源的 EJB 組件,顯示了 J2EE 環境中連接合用資源的必要。您已看到由 JDBC 2.0、JMS 1.02 和 JNDI 1.2 標準擴展 API 定義的設施,和供應商對那些 API 接口實現的支持。雖然特定于供應商的解決方案很健壯,但是對它們的使用卻是以 EJB 的可移植性作為代價的。即將出現的 J2EE Connector Architecture 1.0 解決了該問題,并使資源可插入,從而使 EJB 層從處理特定于供應商的庫中解脫出來。最后,我解釋了為什么您的設計在利用那些合用技術來制作高性能的 J2EE 應用方面扮演著重要角色。
· 參考資料>
· 關于作者
Siva Visveswaran 已有三年以上從事 Java 技術的經歷,并曾對 J2EE 深深著迷。最近,他潛心于 Fortune 100 金融服務公司和 .com 公司的大型復雜 J2EE 應用的體系結構和開發工作。他有著超過 12 年的 IT 行業經歷,目前正作為大型管理咨詢公司的首席顧問,致力于電子商務體系結構、基礎設施技術和內容管理解決方案的工作。Siva 擁有密歇根州底特律 Wayne State 大學的計算機科學碩士學位??梢酝ㄟ^ siva.visveswaran@javaworld.com 與他聯系。
(全文完)
原文轉自:http://www.anti-gravitydesign.com