测试连接服务
WebSphere® Application Server 提供了用于验证数据源配置的测试连接服务。testConnection 操作实例化数据源配置、获取连接,然后立即关闭连接。
如果数据源的定义包含 WebSphere 变量,那么您需要确定变量和数据源的作用域设置影响测试连接结果的方式。下一步是选择使用以下三种方式中的哪一种来激活测试连接服务:通过管理控制台、wsadmin 工具或者 Java™ 独立程序。
验证范围设置
将 WebSphere 变量与数据源配置相关联可引起与应用程序的运行时行为不一致的测试连接结果。在某些情况下,测试连接操作失败,但物理数据源在应用程序运行时期间正常工作。出现潜在冲突的原因是应用程序服务器在运行时处理 WebSphere 变量的作用域设置的方式与它处理测试连接操作的相同作用域设置的方式之间的差异。 了解这些差别可帮助您创建成功的数据源配置。
- 变量的范围可以包含数据源配置;即变量有更大的范围。
- 变量和数据源有完全相同的范围。
数据源范围 | 在其中进行测试连接操作的 JVM |
---|---|
单元 | 管理器进程 |
节点 | (相关节点的)Node Agent 进程 |
集群 | 包含集群成员的每个节点的 Node Agent |
服务器 | 服务器;如果服务器不可用,那么在 Node Agent 中对包含该应用程序服务器的节点重试测试连接操作。 |
![[z/OS]](../images/ngzos.gif)
- 具有驱动程序类型 2 的 IBM Data Server Driver for JDBC and SQLJ 数据源
- 具有驱动程序类型 2 的 DB2 通用 JDBC 驱动程序提供程序数据源
java.sql.SQLException: Failure in loading T2 native library db2jcct2DSRA0010E: SQL state = null, Error Code = -99,999
但是在某些情况下,错误消息可能类似于以下消息:T2zOS exception: [jcc][T2zos]T2zosReusableConnection.flowConnect:initRRSAFAttach
:2528: Connection dead
这些数据源都基于类型 2 JDBC 驱动程序,而这些 JDBC 驱动程序需要访问 T2 本机库。应用程序服务器的运行时环境在服务器进程中提供对数据源的访问,但是测试连接服务在 Node Agent 进程中运行时不提供对这些本机文件的访问。因此,当您在节点范围或者集群范围创建这些数据源时,您可能需要在服务器范围临时创建相同的配置以进行测试。请在服务器级别运行测试连接操作以确定数据源设置是否对于整个配置有效。
数据源范围 | 单元级别变量 | 节点级别变量 | 服务器级别变量 |
---|---|---|---|
单元级别 | 良好 | 失败 | 失败 |
节点级别 | 良好 | 良好 | 失败 |
服务器级别 | 良好 | 良好 | 良好 |
与预期相反,这些测试连接失败通常不会转变为运行时失败。确保每个必须使用数据源的客户机都可以访问 JDBC 驱动程序文件的位置,并使用该位置的完整路径配置 WebSphere 变量。
但是,表 2 中列示的其中一个范围组合可能导致相反的情况:测试连接操作成功,但数据源在运行时失败。如果单元范围的数据源使用单元范围的 WebSphere 变量,那么会出现这种异常情况。因为连接测试操作在 Application Server 可以解析限于单元范围的变量的 Deployment Manager 进程中进行(如表 1 所示),所以该操作成功。因为空值可以覆盖限于单元范围的变量,所以该数据源在运行时失败。
创建节点时,Application Server 会在节点范围为所有受支持的 JDBC 驱动程序创建环境变量,并使用空字符串初始化每个变量。因为应用程序服务器尝试从范围范围的低端到高端解析变量,所以在运行时节点范围变量会覆盖单元范围变量。服务器读取空字符串并接受它作为 JDBC 驱动程序类路径。当该服务器尝试使用数据源时,空类路径会引出 classNotFound 异常。
通过使用其中一个 Application Server 管理选项,可以防止空字符串成为驱动程序类路径变量的最终值。
- 使用 WebSphere Application Server 管理控制台:数据源向导程序将单元范围的变量的值(在 JDBC 提供程序创建向导中指定)复制到相同名称的节点范围的变量。仅当限于节点范围的变量具有空字符串值时,向导程序才执行此复制操作;因此,程序不会更改您先前指定的有效类路径。为了确保在运行时数据源处理限于节点范围的变量,请执行以下步骤:
- 在 Deployment Manager 节点以及数据源必须在其中工作的每个节点上安装 JDBC 驱动程序文件。
- 使用 Deployment Manager 上的驱动程序文件路径在单元作用域定义 JDBC 提供程序的 WebSphere 变量。
- 确保数据源与 Deployment Manager JDBC 提供程序关联,并且具有相同的单元范围。要点: 通过将驱动程序文件安装在以下位置来确保运行时成功:这些位置在所有节点(包括 Deployment Manager 节点)上具有完全相同的完整路径名。否则,可能会重新出现相同方案的测试连接成功,但运行时失败的情形。
- 使用 wsadmin 脚本编制工具:要使数据源可用于测试连接操作和运行时,在单元范围和所有相关节点范围创建相同的驱动程序类路径配置。完成以下步骤:
- 在 Deployment Manager 节点上安装 JDBC 驱动程序文件;使用该路径名在单元范围定义 JDBC 提供程序的驱动程序类路径变量。
- 确保数据源与 Deployment Manager JDBC 提供程序关联,并且具有相同的单元范围。
- 在数据源必须在其中工作的每个节点上,安装
JDBC 驱动程序文件并使用路径在节点作用域定义 JDBC 提供程序的 WebSphere 变量。每个这样的提供程序都必须具有相同的配置。要点: 通过将驱动程序文件安装在以下位置来确保运行时成功:这些位置在所有节点(包括 Deployment Manager 节点)上具有完全相同的完整路径名。否则,可能会重新出现相同方案的测试连接成功,但运行时失败的情形。
仅当所有需要访问数据源的节点(包括 Deployment Manager 节点)在相同平台上运行并且将 JDBC 驱动程序安装在相同位置时,才使用单元范围资源。否则,将节点范围用作数据源的最大范围设置。
忽略变量查询
您可以通过将 JDBC 提供程序的类路径条目更改为硬编码值来绕过环境变量查询。但是,仅当在数据源必须工作的所有节点上以完全相同的方式配置类路径,此策略才会成功。
激活测试连接服务
有三种方式可用来激活测试连接服务:通过管理控制台、wsadmin 工具或 Java 独立程序。 每个进程都调用同一 MBean 上的同一方法。
管理控制台
WebSphere Application Server 允许您只需按下按钮就可从管理控制台来测试连接:数据源连接、数据源设置、V4 数据源集合和 V4 数据源设置页面都有测试连接按钮。在定义并保存数据源之后,您可以单击此按钮以确保此数据源定义中的参数是正确的。在集合页面上,您可以选择多个数据源并同时对其进行测试。注意,首先必须满足某些条件。有关更多信息,请参阅主题“使用管理控制台测试连接”。
对节点 svtaix24Node01 中服务器 server1 上的数据源 isagent 进行测试连接失败,出现以下异常:java.lang.Exception: java.sql.SQLException: JZ006: 捕获到 IOException: java.net.ConnectException: 远程主机拒绝了一个尝试连接操作。DSRA0010E: SQL 状态 = JZ006,错误代码 = 0
当 Sybase 数据源端口号与在
Sybase 服务器中配置的端口不匹配时,就会出现此异常。缺省端口号是 5000。请在 /<sybase 安装目录> 下的接口文件中检查 Sybase 服务器的端口号。wsadmin 工具
wsadmin 工具为所有 WebSphere Application Server 管理活动提供了脚本编制接口。由于测试连接功能作为 MBean 上的方法实现,并且 wsadmin 可以调用 MBean 方法,因此可以使用 wsadmin 测试到数据源的连接。要用 wsadmin 测试数据源连接,您有两种选择:
wsadmin 的 AdminControl 对象具有一个 testConnection 操作,该操作用于测试数据源对象的配置属性。有关信息,请参阅主题“使用 wsadmin 测试连接”。
您还可以通过调用 MBean 操作测试连接。使用本主题中的示例“示例:使用 wsadmin 测试数据源连接”作为此技术的指南。
Java 独立程序
最后,您可以通过执行 DataSourceCfgHelper MBean 上的 testConnection 方法来测试连接。此方法允许您传递配置数据源的配置标识。Java 程序连接到正在运行的 Java 管理扩展 (JMX) 服务器以访问 MBean。在 Application Server 的 WebSphere Application Server Network Deployment 安装中,您连接到在 Deployment Manager 中(通常在端口 8879 上)运行的 JMX 服务器。
此调用的返回值将是 0、正数或异常。0 表明操作成功完成,没有警告。正数表明操作成功完成,但有一些警告。异常表明测试连接失败。
以下样本代码创建数据源实例和相关联的连接实例,并对它们进行测试以确保数据库连接。
此程序使用 JMX 连接到正在运行的服务器,并对 DataSourceCfgHelper MBean 调用 testConnection 方法。注释行中的首字母缩写词 ND 表明以下代码适用于 WebSphere Application Server WebSphere Application Server Network Deployment。注释行中的词语 Base 表明以下代码适用于 WebSphere Application Server。
/**
* Description
* Resource adapter test program to make sure that the MBean interfaces work.
* Following interfaces are tested
*
* --- testConnection()
*
*
* We need following to run
* C:\src>java -Djava.ext.dirs=C:\WebSphere\AppServer\lib;C:\WebSphere\AppServer\java\jre\lib\ext testDSGUI
* must include jre for log.jar and mail.jar, else get class not found exception
*
*
*/
import java.util.Iterator;
import java.util.Locale;
import java.util.Properties;
import java.util.Set;
import javax.management.InstanceNotFoundException;
import javax.management.MBeanException;
import javax.management.MalformedObjectNameException;
import javax.management.ObjectName;
import javax.management.RuntimeMBeanException;
import javax.management.RuntimeOperationsException;
import com.ibm.websphere.management.AdminClient;
import com.ibm.websphere.management.AdminClientFactory;
import com.ibm.ws.rsadapter.exceptions.DataStoreAdapterException;
public class testDSGUI {
//Use port 8880 for a Base installation or port 8879 for ND installation
String port = "8880";
// String port = "8879";
String host = "localhost";
final static boolean verbose = true;
// eg a configuration ID for DataSource declared at the node level for Base
private static final String resURI = "cells/cat/nodes/cat|resources.xml#DataSource_1";
// eg a 4.0 DataSource declared at the node level for Base
// private static final String resURI = "cells/cat/nodes/cat|resources.xml#WAS40DataSource_1";
// eg Apache Derby DataSource declared at the server level for Base
//private static final String resURI = "cells/cat/nodes/cat/servers/server1/resources.xml#DataSource_6";
// eg node level DataSource for ND
//private static final String resURI = "cells/catNetwork/nodes/cat|resources.xml#DataSource_1";
// eg server level DataSource for ND
//private static final String resURI = "cells/catNetwork/nodes/cat/servers/server1|resources.xml#DataSource_4";
// eg cell level DataSource for ND
//private static final String resURI = "cells/catNetwork|resources.xml#DataSource_1";
public static void main(String[] args) {
testDSGUI cds = new testDSGUI();
cds.run(args);
}
/**
* This method tests the ResourceMbean.
*
* @param args
* @exception Exception
*/
public void run(String[] args) {
try {
System.out.println("Connecting to the application server.......");
/*************************************************************************/
/** Initialize the AdminClient */
/*************************************************************************/
Properties adminProps = new Properties();
adminProps.setProperty(AdminClient.CONNECTOR_TYPE, AdminClient.CONNECTOR_TYPE_SOAP);
adminProps.setProperty(AdminClient.CONNECTOR_HOST, host);
adminProps.setProperty(AdminClient.CONNECTOR_PORT, port);
AdminClient adminClient = null;
try {
adminClient = AdminClientFactory.createAdminClient(adminProps);
} catch (com.ibm.websphere.management.exception.ConnectorException ce) {
System.out.println("NLS: Cannot make a connection to the application server\n");
ce.printStackTrace();
System.exit(1);
}
/*************************************************************************/
/** Locate the Mbean */
/*************************************************************************/
ObjectName handle = null;
try {
// Send in a locator string
// eg for a Base installation this is enough
ObjectName queryName = new ObjectName("WebSphere:type=DataSourceCfgHelper,*");
// for ND you need to specify which node/process you would like to test from
// eg run in the server
//ND: ObjectName queryName = new OjectName
("WebSphere:cell=catNetwork,node=cat,process=server1,type=DataSourceCfgHelper,*");
// eg run in the node agent
//ND: ObjectName queryName = new ObjectName
("WebSphere:cell=catNetwork,node=cat,process=nodeagent,type=DataSourceCfgHelper,*");
//ND: eg run in the Manager
//ND: ObjectName queryName = new ObjectName
("WebSphere:cell=catNetwork,node=catManager,process=dmgr,type=DataSourceCfgHelper,*");
Set s = adminClient.queryNames(queryName, null);
Iterator iter = s.iterator();
while (iter.hasNext()) {
// use the first MBean that is found
handle = (ObjectName) iter.next();
System.out.println("Found this ->" + handle);
}
if (handle == null) {
System.out.println("NLS: Did not find this MBean>>" + queryName);
System.exit(1);
}
} catch (MalformedObjectNameException mone) {
System.out.println("Check the program variable queryName" + mone);
} catch (com.ibm.websphere.management.exception.ConnectorException ce) {
System.out.println("Cannot connect to the application server" + ce);
}
/*************************************************************************/
/** Build parameters to pass to Mbean */
/*************************************************************************/
String[] signature = { "java.lang.String" };
Object[] params = { resURI };
Object result = null;
if (verbose) {
System.out.println("\nTesting connection to the database using" + handle);
}
try {
/*************************************************************************/
/** Start to test the connection to the database */
/*************************************************************************/
result = adminClient.invoke(handle, "testConnection", params, signature);
} catch (MBeanException mbe) {
// ****** all user exceptions come in here
if (verbose) {
Exception ex = mbe.getTargetException(); // this is the real exception from the Mbean
System.out.println("\nNLS:Mbean Exception was received contains" + ex);
ex.printStackTrace();
System.exit(1);
}
} catch (InstanceNotFoundException infe) {
System.out.println("Cannot find" + infe);
} catch (RuntimeMBeanException rme) {
Exception ex = rme.getTargetException();
ex.printStackTrace(System.out);
throw ex;
} catch (Exception ex) {
System.out.println("\nUnexpected Exception occurred:" + ex);
ex.printStackTrace();
}
/*************************************************************************/
/** Process the result. The result will be the number of warnings */
/** issued. A result of 0 indicates a successful connection with */
/** no warnings. */
/*************************************************************************/
//A result of 0 indicates a successful connection with no warnings.
System.out.println("Result=" + result);
} catch (RuntimeOperationsException roe) {
Exception ex = roe.getTargetException();
ex.printStackTrace(System.out);
} catch (Exception ex) {
System.out.println("General exception occurred");
ex.printStackTrace(System.out);
}
}
}