程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 連接池 - 深入J2EE的連接合用

連接池 - 深入J2EE的連接合用

編輯:關於JAVA

Java 2 Enterprise Edition (J2EE) 規范提供了實現高度可伸縮、可靠和可 用的電子商務應用的分布式基於服務的體系結構。通常,J2EE 應用體系結構與 模型-視圖-控制器 (MVC) 框架相對應 -- 資源庫/外部系統資源支持域模型( 模型),JSP/Servlet 管理顯示(視圖),而 EJB 處理商業邏輯(控制器)。

通過服務器端所有三層中的組件實現一個典型的電子商務應用用例。考慮到 用戶交互數量的龐大(對於面對客戶的應用,有上百萬個),需要優化地共享有 限的服務器端資源。這類資源可能包括數據庫、消息隊列、目錄、企業系統 (SAP、CICS) 等等,它們中的每一個都可以由使用代表資源訪問點的連接對象的 應用來訪問。管理對那些共享資源的訪問對於滿足 J2EE 應用的高性能需求來說 至關重要。

連接合用是由數據庫供應商倡導的技術,其目的是允許客戶機共享一組高速 緩存的連接對象,這些對象提供對數據庫資源的訪問。在本文中,我分析了 J2EE 環境中服務器端資源(例如數據庫、消息隊列、目錄和企業系統)的連接 合用。

為何合用資源連接?

考慮一下 代碼示例 ,其中,EJB 使用 JDBC 1.0、 不使用連接合用來訪問 數據庫資源。

很明顯,該示例的主要問題是連接的打開和關閉。考慮到實體 bean 是共享 組件,因此,對每個客戶機請求,都要進行幾次獲取和釋放數據庫連接的操作。

從圖 1 可以看出,使用 JDBC 1.0 通過數據庫管理器獲取和釋放數據庫連接 將影響 EJB 層的性能。這種影響是由數據庫資源管理器進程創建和摧毀那些對 象而引起的。應用服務器一般需要花 1 到 3 秒的時間來建立數據庫連接(包括 與服務器通信、認證等等),並需要對每一個客戶機 (EJB) 的請求進行連接。

圖 1. 使用 JDBC 1.0 的連接管理

 

使用服務供應商設施的連接合用

現在看一下在 J2EE 環境中,數據庫和非數據庫資源類型當前可以使用哪些 連接合用設施。

JDBC 2.0 標准擴展 API
JDBC 2.0 標准擴展 API 指定數據庫服務供應商可以實現具有以下特性的合用 技術:允許請求客戶機透明地共享資源池的多個連接對象。在那種情況下,因為 池管理器預先在啟動時創建連接對象,所以,J2EE 組件可以使用連接對象,而 不會導致數據庫資源管理器上的系統開銷。應用服務器供應商在其內存空間實現 池管理器,並根據需要動態改變池的大小,從而優化資源的使用。圖 2 中顯示 了這種情況。

圖 2. 使用 JDBC 2.0 標准擴展的連接合用

通過使用 DataSource 接口 (JDBC 2.0) 或 DriverManager (JDBC 1.0) 接 口,J2EE 組件可以獲得物理數據庫連接對象。要獲得邏輯(合用的)連接, J2EE 組件必須使用以下這些 JDBC 2.0 合用管理器接口:

javax.sql.ConnectionPoolDataSource 接口,該接口充當合用的 java.sql.Connection 對象的資源管理器連接 factory。每家數據庫服務器供應 商都提供該接口的實現(例如,Oracle 實現 oracle.jdbc.pool.OracleConnectionPoolDataSource 類)。

javax.sql.PooledConnection 接口,該接口封裝到數據庫的物理連接。同樣 ,數據庫供應商提供其實現。

對於那些接口和 XA 連接的每一個,都存在一個 XA(X/Open 規范)等價定 義。

以下代碼示例顯示了 EJB 應用如何利用合用的連接對象來訪問數據庫資源( 基於 JDBC 2.0)。本例中的 EJB 組件使用 JNDI 查詢來確定數據庫連接池資源 的位置。JNDI 1.2 標准擴展 API 允許 Java 應用以相同的方式訪問位於完全不 同的目錄和命名系統中的對象。使用 JNDI API,應用可以查詢目錄來確定任何 資源(例如,數據庫服務器、LDAP 服務器、打印服務器、消息服務器、文件服 務器等等)的位置。

請注意: 實際代碼可能會根據數據庫供應商實現類的不同而不同。

以上代碼(使用 JDBC 2.0)和使用 JDBC 1.0 的主要不同在於: getConnection() 從池中獲取已打開的連接,而 close() 只將連接對象釋放回 池。如今,幾乎每一家數據庫服務器供應商(如 Oracle、DB2、Sybase 和 Informix)都提供 JDBC 2.0 驅動程序。如今大多數應用服務器供應商(IBM、 BEA、iPlanet、IONA 等)也都支持 JDBC 2.0。

應該說明的一點是:如今,幾乎所有應用服務器都采用兩層連接合用體系結 構,其中,池位於應用服務器內存空間(與獨立的連接代理不同)。

JMS 1.02 標准擴展 API
J2EE 應用組件可以使用消息傳遞資源與其它企業應用異步通信。JMS 1.02 標 准擴展 API 提供獨立於供應商的方式來與消息傳遞服務供應商通信。與數據庫 資源一樣,通過使用可以合用的連接對象來訪問消息隊列。

JMS 1.02 API 包括下列接口以支持資源合用:

用於 factory 對象的 javax.jms.QueueConnectionFactory 或 javax.jms.TopicConnectionFactory

用於連接對象的 javax.jms.QueueConnection 或 javax.jms.TopicConnection

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 客戶機所用的類:

public class netscape.ldap.util.ConnectionPool extends  java.lang.Object
methods: Connection(), getConnection(), close(), etc.

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.cci.ConnectionFactory 和 javax.resource.cci.Connection ,分別作為連接 factory 和連接的接口 -- 與上一節中提到的 JDBC 2.0 接口 類似。

圖 3. J2EE Connector Architecture 1.0 中的資源適配器

Connector 1.0 中的連接合用

Connector 1.0 的編程模型如下:

EJB 執行連接 factory 的 JNDI 查詢,然後發出 getConnection() 請求。

連接 factory 將請求委托給 ConnectionManager 。

連接管理器在應用服務器中查詢連接池的實例。如果沒有可用的連接池,則 管理器使用 ManagedConnectionFactory 來創建一個物理(不合用的)連接。

在那種情況下,假定資源適配器供應商實現接口。然而,連接器體系結構並 不指定應用服務器如何實現連接池,而是提供一些指示,例如,根據適配器類型 、服務質量 (QoS) 需求等來劃分連接池。

例如,基於即將出現的 EJB 2.0 連接器體系結構的、至企業/舊有系統的 Sun 連接器的產品版 iPlanet Unified Integration Framework Toolkit v 6.0 ,為 EJB 層可能要訪問的每個後端系統定義了連接池。一個定期執行的線程監 控池對象的使用和壽命。

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 應用方面扮演著重要角色 。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved