Rahul Kitchlu, IBM 多伦多实验室
Jason Shayer, IBM 多伦多软件实验室
2002 年 12 月 在访问 DB2 for OS/390 or z/OS server 的三层应用程序中,并不自动发送重要的客户机信息。DB2 Connect 提供可用来将详细客户机信息(如应用程序名称、用户标识、工作站名称和记帐字符串)发送到 DB2 for OS/390 的本机 API。可从该 API 的 C 接口或 JDBC 编程接口,或直接从 WebSphere Administrative Console 访问该 API。
简介
如果您负责开发和交付用于访问 DB2® 服务器上数据的三层结构应用程序,您可能已经发现,传递用于正确监控客户机并对其记帐所需的信息是比较困难的。在典型的方案中,运行于 WebSphere® Application Server 之上且访问 DB2 服务器上数据的应用程序对于 DB2 是不可区分的。像 WebSphere 这样的应用程序服务器可以通过数据库连接池来缩短响应时间,管理员也很容易通过命令从 DB2 得到这些连接的句柄。但是,因为使用这些连接的应用程序运行在 WebSphere Java™ 虚拟机(JVM)中,所以它们在缺省情况下不能提供任何有关连接的附加信息。
例如, 图 1 所演示的是在我们更改环境以设置有关进入的客户机的附加信息之前,DB2 for z/OS and OS/390 上 DISPLAY THREAD(*) 命令的输出。应用程序的名称被标识为 java.exe ,用户标识和工作站缺省值为用于获取数据库连接的用户标识和工作站。有些情况下,需要设置有关当前正在运行的应用程序和模块的进一步模块化信息,对于这类需求,该命令返回的信息可能并不充足。
图 1. 在我们设置客户机信息之前
通过 DB2 LIST APPLICATIONS 命令可以查看 DB2 for UNIX、DB2 for Windows 和 DB2 for Linux 上的客户机连接,如下所示:
> db2 list applications
Auth Id Application Appl. Application Id DB # of
Name Handle Name Agents
-------- -------------- ---------- ------------------------------ -------- -----
DB2V71 java.exe 195 *LOCAL.db2v81.07B0C0003412 SAMPLE 1
DB2V71 java.exe 169 G91A59AF.O17A.0BA7C0210130 SAMPLE 1
|
为解决这一问题,DB2 提供了一个本机 API(SQLESETI),可以用它来从应用程序设置有关客户机的附加信息。可以从该 API 的 C 接口,从 JDBC 编程接口或直接从 WebSphere Admininstrative Console 访问该 API。本文详细描述了如何设置环境以便与 WebSphere Application Server 发出的每个 DB2 连接请求一起来传递更多客户机信息。这些信息可以是应用程序名称、用户标识、工作站名称或记帐字符串。
我们的示例假设有一个由以下产品组成的环境:
- DB2 Universal Database™ for OS/390®(V6 或更高版本)
- DB2 Connect™(运行 DB2 Connect Enterprise Edition V7.1 或更高版本)
- WebSphere® Application ServerAdvanced Edition(V4.0.1 或更高版本)
本文包括以下内容:
- 对于关键体系结构组件的简要概念性介绍。
- 设置 DB2 上正确客户机信息的过程,以便使应用程序监控和资源记帐更有效。为了演示 WebSphere 与 DB2 的紧密集成,您可以从 WebSphere Application Server Console 中的 Data Sources 选项卡直接配置这些信息。只有将 DB2 与 WebSphere Application Server 一起使用时,这一特性才可用。
- 关于如何使用 DB2 API 通过 Java 程序设置客户机信息的指示信息。这样的应用程序的样本代码可以通过 下载获得。
环境
本文适用的典型环境是三层结构的设置,在这样的环境中,运行在 WebSphere 上的应用程序通过中间层(DB2 Connect Enterprise Edition)与 DB2 数据库(本例中是 DB2 for OS/390)建立连接。
图 2. 本文中描述的三层结构环境
DB2 通用数据库(UNIX、Windows 和 Linux)
DB2 通用数据库是 IBM 的关系数据库管理系统,可运行在 AIX®、Linux、HP-UX、Sun 和 Windows® 等几乎全部主流平台。DB2 数据库软件标志着关系数据库发展的新阶段,是业界第一个在可靠性、性能和可伸缩性方面都有优异表现,并提供一流的多媒体处理能力和高度 Web 集成的关系数据库管理系统。
DB2 通用数据库 for z/OS and OS/390
DB2 for OS/390 and z/OS,V7 程序为电子商务和数据仓库应用程序提供了改进的性能、可用性和可伸缩性。
通过使用 DB2 UDB for OS/390 and z/OS,V7,您的电子商务和商业智能应用程序可与运行 OS/390 和 z/OS 的 S/390® 和 zSeries™ 服务器提供的功能强大、高度可用的环境相协同。您可以在开发和扩展您今后的电子贸易的同时利用现有应用程序。
DB2 Connect
DB2 Connect 为您的应用程序提供对大型机服务器(S/390、zSeries、AS/400® 和 iSeries™)的无缝访问点。如果想要访问主机上的 DB2 数据,则可以使用 DB2 Connect 来支持从 Windows® 和 UNIX® 平台对该数据快速且安全的访问。
WebSphere Application Server
IBM WebSphere Application Server V5 及其开发环境 WebSphere Studio V5 为集成跨企业与伙伴、供应商和客户的业务流程提供了基于标准的基础设施。
设置客户机信息 — 概述
您可以在连接边界上或在事务边界上设置客户机信息。
- 在连接边界上
通过使用 JDBC 接口,您可以在首次获得数据库连接时设置附加客户机信息。您可以从应用程序的数据库连接代码或直接从 WebSphere Administrative Console 使用这一特性。从控制台在连接边界设置缺省客户机信息比较简单,因为您可以使用 WebSphere 提供的图形用户界面而无需任何额外开销。
- 在事务边界上
如您需要在建立连接后更改客户机信息,可以从 C 接口(该方案的示例可在 DB2 Samples 目录中获得)或从 Java 接口(使用 JNI 封装器调用必需的 C 代码)手工调用 DB2 SQLESETI API。在某些情况下,您可能需要在事务边界上而不是连接边界上设置客户机信息。例如,如果您的应用程序在同一连接模块中包含多个方法,则您可能需要标识每个方法或进程,因而需要在每个事务中设置客户机信息。
在连接边界上设置客户机信息
您可以使用 WebSphere Administrative Console或通过使用 Java 程序来设置客户机信息。
使用 WebSphere Administrative Console
您可以直接从 WebSphere Application Server(Advanced Edition for Multiplatforms,V4.1)Console 中的 Data Sources 选项卡配置客户机信息:
- 启动 WebSphere Administrative Console。
- 单击 Resources和 JDBC Provider。
- 在 JDBC Provider上单击鼠标右键,然后单击 New。请查询您的 WebSphere 文档以获得有关创建新驱动程序的更多信息。
- 选择您创建的驱动程序,然后选择 Data Source。
- 从位于 Custom Properties框中的 General 选项卡,添加以下的任一或全部参数(及其相应的值):
ClientApplName
ClientWrkstnName
ClientUserid
ClientAcctStr
|
- 单击 Apply结束配置。
使用 Java 程序
以下代码向您演示了如何使用 DB2ConnectionPoolDataSource 类来将客户机信息传递到服务器。
DB2ConnectionPoolDataSource ds = new DB2ConnectionPoolDataSource();
ds.setUser("myuser");
ds.setPassword("mypass");
ds.setDatabaseName("mydb");
ds.setConnectionAttribute
("ClientApplName=WebSphere-Samples;
ClientWrkstnName=WebSphere-Wkstn;
ClientUserid=WebSphere-User
ClientAcctStr=WebSphere-Acctstr");
PooledConnection poolconn = ds.getPooledConnection();
con = poolconn.getConnection();
|
在事务边界上设置客户机信息
作为在连接边界上设置客户机信息的替代方案,您可以选择在事务边界上设置信息。本节描述如何在用 Java 编写的应用程序代码中在事务边界上设置或复位客户机信息。要做到这一点,可手工调用 JNI 封装器以调用必需的 C 代码。对于这一讨论,我们提供一个典型的 Java 类来调用 JNI 封装器类,后者依次调用本机 API。您可以使用为您的应用程序提供的代码,也可以开发自己的 JNI 桥接代码。
先决条件
确保:
- 在建立连接之后调用该 JNI 封装器。
- 在任何事务之前调用该 JNI 封装器。
- 对每个需要设置客户机信息的应用程序调用该 JNI 封装器。
- 正确设置 DB2 和 Java 环境变量。
限制
DB2 for UNIX、DB2 for Windows 和 DB2 for Linux 平台都支持 SQLESETI API,但是,随本文提供的 Java 接口和 JNI 封装器只使用了以下软件进行开发和测试:
- IBM® DB2 Connect Enterprise Edition 7.2
- JDK(1.2.2 和 1.3)
- AIX 4.3.3
- WebSphere Application Server V4.0.1
- DB2 for OS/390 and z/OS V6 和 V7
过程
以下过程描述了使用 JNI 封装器实现 SQLESETI API 的 Java 接口( seti.java )的循序渐进的方法。
- 首先我们需要编写定义“本机”方法的 Java 类。我们将该接口命名为
seti.java
- 我们编译该 Java 类以获取 JNI 头文件:
javac seti.java 是编译代码的命令。
javah -jni seti 是生成 JNI 头文件的命令。
seti.h 是机器生成的 JNI 头文件。
- 扩充 JNI 头文件以用 C 实现调用该 API 的代码。
sapi.c 是调用 SQLESETI API 的 C 代码。
- 根据操作系统和正确的 DB2 include 文件,以正确的编译设置编译 C 代码。我们在 IBM AIX 机器上实现了这一代码,所以下面是在 AIX 上编译该 C 代码的命令:
xlc -I$DB_HOME/include -I$JAVA_HOMEinclude -c sapi.c -O
|
这一步的输出是 sapi.o 。
- 从已编译的代码生成共享库。以下是在 AIX 上生成共享库的命令:
cc -o libseti.so sapi.o -I$DB_HOME/include -I$JAVA_HOME/include
-L$DB_HOME/lib -bE:seti.exp -bM:SRE -e Java_seti_app -ldb2 -lc
|
libseti.so 是该步骤的输出。
提示:可以在其它平台上实现第 4 和第 5 步,如下所示:
Linux
gcc -o libseti.so -shared -Wl, -soname,libseti.so
-I$DB_HOME/include -I$JAVA_HOME/include -I$JAVA_HOME/include/linux sapi.c -static -lc
|
Windows
cl -I%JAVA_HOME%/include -I$DB_HOME/include -I%JAVA_HOME%/include/win32
-LD sapi.c -Felibseti.dll
|
Solaris
cc -G -I$JAVA_HOME/include -I$DB_HOME/include
-I$JAVA_HOME/include/solaris \ sapi.c -o libseti.so
|
Java 应用程序已经为调用该 Java 接口( seti.java )做好准备,该接口装入共享库(来自第 5 步)以调用 JNI 封装器,进而调用本机方法(例如 test.java )。
以上过程中提到的所有代码都可以通过 下载获得。
事务处理器监控程序的介入
在事务监控程序或应用程序服务器(多层)环境中,应用程序用户不直接发出 SQL 请求。相反,它们向事务处理器监控程序(例如运行在 UNIX、OS/2® 或 Windows NT® 服务器上的 CICS®、TUXEDO 或 ENCINA)或应用程序服务器提出请求以执行业务事务。每个业务事务都有一个应用程序部件向数据库服务器发出 SQL 请求。因为 SQL 请求是由中间层服务器发出的,所以数据库服务器没有关于导致该 SQL 请求执行的初始客户机的信息。
有关事务处理器监控的更多信息,请参阅 DB2 Connect User's Guide。
事务处理器监控程序(TP 监控程序)事务或应用程序服务器代码的开发人员可使用 SQLESETI API 来向数据库服务器提供有关初始客户机的信息。
您可以使用 seti.java (请参阅 下载部分)或 JDBC Connection 属性将这些客户机信息传递到数据库服务器。
现在让我们研究一下在 DB2 for UNIX、DB2 for Windows 和 DB2 for Linux 上监控这些应用程序客户机的情形。假设我们在一台运行 DB2 V7.2 的 AIX 4.3.3 机器上对一个远程数据库(AIX 5.1,DB2 V7.2)编目,并使用 seti.java 运行我们的测试应用程序来设置客户机信息。在 DB2 服务器上,我们可以通过使用以下命令看到这些信息是如何被发送的:
- 在服务器上,打开 DB2 监控功能:
db2 update monitor switches using
table on bufferpool on uow on sort on lock on statement on
|
- 在服务器上,复位数据库的监控程序开关
db2 reset monitor for database <dbname>
|
- 在客户机上,运行应用程序。
- 在服务器上,进行应用程序级别的快照:
db2 get snapshot for applications on <dbname>
|
该快照应具有与下面相似的内容:
...
...
TP Monitor Client User ID: WebSphere-Userid
TP Monitor Client Workstation Name: WebSphere-Wrkstn
TP Monitor Client Application Name: WebSphere-AppName
TP Monitor Client Accounting String: WebSphere-AccStr
...
...
|
可以用这些 TP Monitor 元素来标识 WebSphere Application Server 连接。
DISPLAY THREAD 上显示的结果
图 4演示了设置客户机信息之后,在 DB2 for OS/390 and z/OS 服务器上运行 DISPLAY THREAD(*) 命令的输出。请注意应用程序名、用户标识和工作站名都已被设置为我们以前指定的值。
图 4. 客户机信息现在出现在 DISPLAY THREAD 中
有关 SQLESETI C API 的更多信息
SQLESETI 是一个随 DB2 一起提供的 C API,如果连接已经存在,则可用它设置特定于连接的客户机信息。该 API 仅用于向 DB2 UDB V6 或更高版本以及 DB2 OS/390 V5 或更高版本传递信息。
使用 SQLESETI API 能够指定的信息类型
应用程序可指定以下类型的信息:
- 正在被设置或查询的客户机用户标识。最多可设置 255 个字符,然而服务器可将该值截断为某个特定于平台的值。该用户标识仅用于身份识别目的,并不用于任何授权。
- 正在被设置或查询的客户机工作站名称。最多可设置 255 个字符,然而服务器可将该值截断为某个特定于平台的值。
- 正在被设置或查询的客户机应用程序名称。最多可设置 255 个字符,然而服务器可将该值截断为某个特定于平台的值。
- 正在被设置或查询的客户机记帐字符串。最多可设置 200 个字符,然而服务器可将该值截断为某个特定于平台的值。
下面列出了 SQLE-CLIENT-INFO TYPE 元素的有效项和每一项的相关描述:
表 1. 客户机信息设置
| 类型 |
数据类型 |
描述 |
| SQLE_CLIENT_INFO_USERID |
CHAR(255) |
客户机的用户标识。有些服务器会截断该值。例如,DB2 for OS/390 服务器支持的最大长度是 16。该用户标识仅用于身份识别目的,并不用于任何授权。 |
| SQLE_CLIENT_INFO_WRKSTNNAME |
CHAR(255) |
客户机的工作站名称。有些服务器会截断该值。例如,DB2 for OS/390 服务器支持的最大长度是 18。 |
| SQLE_CLIENT_INFO_ APPLNAME |
CHAR(255) |
客户机的应用程序名称。有些服务器会截断该值。例如,DB2 for OS/390 服务器支持的最大长度是 32。 |
| SQLE_CLIENT_INFO_ ACCTSTR |
CHAR(200) |
客户机的记帐字符串。有些服务器会截断该值。例如,DB2 for OS/390 服务器支持的最大长度是 200。 |
结束语
对将数据库作为后端使用的应用程序进行监控和审计正成为越来越困难的任务。访问 DB2 服务器的应用程序可使用 SQLESETI API 在数据库连接或事务级别设置相关的客户机信息(如应用程序名称、用户标识、工作站名称和记帐字符串)。可在 Java 应用程序中使用 JDBC 接口或直接从 WebSphere Administrative Console 在连接边界上设置该信息。在事务边界上,可使用调用 SQLESETI API 的 JNI 封装器类来编码自己的 Java 接口。
相关信息
- SQLESETI API 信息
- IBM DB2 产品信息
- IBM WebSphere 产品信息
作者简介
Rahul Kitchlu是 IBM 多伦多软件实验室 DB2 集成团队的软件工程师。Rahul 在 University of New Brunswick 获得计算机科学学士学位,现在是 IBM 认证的解决方案专家(IBM Certified Solutions Expert)。他目前主要关注的是 DB2-WebSphere 集成。可以通过 rkitchlu@ca.ibm.com与 Rahul 联系。 |
|
Jason Shayer是 IBM 多伦多软件实验室 DB2 通用数据库团队的信息开发人员。Jason 在 University of Waterloo 获得数学与英语学士学位,他在 DB2 信息开发部门工作了 5 年多。他目前是 DB2 文档的 Quick Beginnings 组件团队负责人。可以通过 shayer@ca.ibm.com与 Jason 联系。
|
|