WAS配置存储库结构
WAS 的所有资源的配置信息都是以 XML 形式存储在 WAS 配置存储库中的。无论用户使用管理控制台还是 wsadmin 里的 AdminConfig 或 AdminTask 命令对 WAS 进行配置,本质上都是对 WAS 配置存储库中的 XML 文件进行编辑和修改。例如,我们在打开安全管理设置选项时,如图 1 所示,在管理控制台操作和使用 wsadmin 命令最终的结果都是将 security.xml 文件中的 enabled 属性值从 false 改为 true。
因为 WAS 的各种类型的资源对象以及属性在 wsadmin 命令中的层次关系和在配置存储库中所处的位置和文件目录层次结构是一致的,所以要想深入了解如何定位一个 WAS 资源以及它的属性,我们就需要掌握 WAS 配置存储库的层次结构以及各种类别的 WAS 资源在储藏室中的位置。WAS 的配置存储库是存储在主概要文件里的 config 目录下(例如,在我的系统中的路径是 %WAS_HOME%/profiles/Dmgr01/config
)。我们先来看一下它的大体目录文件结构:
图 2.WAS 配置存储库层次结构
在这里我将WAS常用的资源按配置管理角度大致分为以下几类:
文件名称 | 所承载的WAS资源 | 所处位置 |
deployment.xml | 应用的部署信息,包括targetmapping,module,classloader等 | 各个应用的 deployments 目录下 |
有一点要说明的是 wsadmin 里提供了 AdminApp 命令,该命令可以很好的处理更改应用部署配置信息的问题,所以我们通常不会用 AdminConfig 命令去直接更改应用的配置信息. 因此,在这里就不再举例说明如何用 AdminConfig 命令定位应用部署配置里的对象以及属性了。
文件名称 | 所承载的 WAS 资源 | 所处位置 |
resource.xml | JDBC Provider/ DataSource/ JMS /Mail Server/URL 等 | 各个级别都存在 |
variables.xml | 环境变量信息 | 各个级别都存在 |
resources-pme.xml | Scheduler/work manager | 各个级别都存在 |
libraries.xml | 共享类库信息 | 各个级别都存在 |
文件名称 | 所承载的 WAS 资源 | 所处位置 |
server.xml | 定义了 Server 配置信息,注意: dmgr 和 nodeagent 也是特殊类型的服务器,所以他们底下也会有同样的配置文件 | 在所有的应用服务器目录下,包括 dmgr 和 nodeagent。 |
serverindex.xml | 定义了一个 node 下所有应用服务器(包括 nodeagent)以及所使用的通讯端口信息 | 在 node 级别下 |
文件名称 | 所承载的 WAS 资源 | 所处位置 |
security.xml | WAS 管理安全相关的信息 | 只在 Cell 级别下 |
admin-authz.xml | 定义管理操作的角色 | 只在 Cell 级别下 |
virtualhosts.xml | 虚拟主机信息 | 只在 Cell 级别下 |
文件名称 | 所承载的 WAS 资源 | 所处位置 |
sib-bus.xml | 定义了 SIBus 的配置信息 | 只在 Cell 底下的 buses 目录下 |
sib-authorisations.xml | 定义了 SIBus 授权信息 | 只在 Cell 底下的 buses 目录下 |
sib-destinations.xml | 定义了 SIBus 目的信息 | 只在 Cell 底下的 buses 目录下 |
大概了解了哪些资源在哪些目录的哪些 XML 文件中,我们就能容易地在 wsadmin 中定位一个资源对象的配置标识以及修改它的属性了。下面就通过几个具体实例,让读者掌握解决实际问题的具体操作步骤和方法。
资源对象的定位及属性修改的方法和实例
首先,我们将通过第一个实例详细讲解如何采用结合配置管理控制台的方法来定位资源对象及修改其属性。
实例 1.修改一个队列连接工厂最大最小连接数属性
定位并修改这个属性难点在于属性所在位置层次比较深,并不是队列连接工厂的直接属性,而是下两层子对象的属性,所以要逐层确定子对象,再找到属性进行修改。
1. 定位所要修改的资源属性所在的具体 xml 文件
本例中所修改的队列连接工厂是 Cell 级别的,对照上面的表格,应该比较清楚的知道 JMS 的配置信息都会存储在 Cell 级别下的 resource.xml 文件中。如果遇到不太确定的情况,也可以通过在管理控制台上修改属性的方法来定位属性所在 xml 文件的路径,对于此例,我们可以先在管理控制台上进行修改:
图 3.队列链接工厂连接池
修改完属性值,点击确定按钮,会有保存工具条出现,如图 4 所示:
图 4.保存修改配置页面
这个时候不要点击“保存”,先点击“查看”
展开“更改的文档总数”,可以看到哪些配置信息文件将被更新。这个就是被更改属性对象所在的文件。
2. 定位属性所属对象,和对象层次关系。
接上一步,先不要点击“保存”按钮,而是到主配置概要文件目录下找到该文件。把未经修改的文件拷贝到一个临时目录下进行备份。然后点击“保存”按钮。这个时候 resource.xml 已经被更新,我们把新旧两个文件用文件比较器 (例如 Linux 和 UNIX 系统提供的 diff 文件比较命令) 比较一下,就会找到我们在管理控制台上更改的属性在 resource.xml 中的具体位置:
清单 1.队列连接工厂的资源文件片段
<connectionPool xmi:id="ConnectionPool_1227757314565" connectionTimeout="180" maxConnections="150" minConnections="40" reapTime="180" unusedTimeout="1800" agedTimeout="0" purgePolicy="EntirePool" numberOfSharedPoolPartitions="0" numberOfUnsharedPoolPartitions="0" numberOfFreePoolPartitions="0" freePoolDistributionTableSize="1" surgeThreshold="-1" surgeCreationInterval="0" testConnection="false" testConnectionInterval="0" stuckTimerTime="0" stuckTime="0" stuckThreshold="0"/>
可以看出 maxConnections 和 minConnections 这两个属性被更改。
打开更新后的 resource.xml 文件(如图6所示),找到这两个属性
通过 XML 编辑器我们可以看到明确的层次关系:
清单 2.队列连接工厂层次关系
<resources.j2c:J2CResourceAdapter xmi:id="J2CResourceAdapter_1227446137382" name="SIB JMS Resource Adapter"…> factories xmi:type="resources.j2c:J2CConnectionFactory" name="TradeBrokerQCF" …> <connectionPool xmi:id="ConnectionPool_1227757314565" maxConnections="200" minConnections="50" …>
说明这个两个属性是 ConnectionPool 对象的属性,ConnectionPool 是 J2CConnectionFactory 的子对象,而 J2CConnectionFactory 又是最上层 J2CResourceAdapter 的子对象。这样我们就清楚知道了如何从一个 J2CResourceAdapter 对象一级一级的找到这两个属性了。
3.在 wsadmin 里中逐层找到属性所在的资源对象
可以用 AdminConfig.list() 命令逐层去找,也可以用 AdminConfig.getid() 命令直接定位到对象的配置标识。在 AdminConfig.getid() 命令的输入参数中,我们可以指定配置对象的分层包含路径(例如/<type>:<name>/<type>:<name>/..., 如果指定类型没有名称或者在此类别下只有唯一个对象,name 可以省略),从最外层的 Cell 级开始一直指定到 ConnectionPool 对象,例如:
wsadmin>AdminConfig.getid( '/Cell:/J2CResourceAdapter:/J2CConnectionFactory:/ConnectionPool:/') '(cells/cuixx02Cell01|resources.xml#ConnectionPool_1227757314565)/r/n( cells/cuixx02Cell01|resources.xml#ConnectionPool_1227757314923)'
4. 查看和修改所需属性值
最后一步就是修改属性了,对于属性不是很多的对象,通常会用 AdminConfig.showall() 查看一下所有属性,然后找出需要修改的属性进行修改:
清单 3.列出队列连接工厂属性
wsadmin>connection = AdminConfig.getid( '/Cell:/J2CResourceAdapter:/J2CConnectionFactory:TradeBrokerQCF/ConnectionPool:/') wsadmin>print AdminConfig.showall(connection) [agedTimeout 0] [connectionTimeout 180] [freePoolDistributionTableSize 1] [maxConnections 200] [minConnections 50] [numberOfFreePoolPartitions 0] [numberOfSharedPoolPartitions 0] [numberOfUnsharedPoolPartitions 0] [properties []] [purgePolicy EntirePool] [reapTime 180] [stuckThreshold 0] [stuckTime 0] [stuckTimerTime 0] [surgeCreationInterval 0] [surgeThreshold -1] [testConnection false] [testConnectionInterval 0] [unusedTimeout 1800]
因为 wsadmin 里的所有 WAS 对象属性名称跟 xml 文件里所使用的名称是完全一致的,所以从 resource.xml 文件中也可以直接得到确切的属性名,然后对其值进行修改:
清单 4.资源配置文件中的队列连接工厂的连接池属性
<connectionPool xmi:id="ConnectionPool_1227757314565" connectionTimeout="180" maxConnections="200" minConnections="50" reapTime="180" unusedTimeout="1800" agedTimeout="0" purgePolicy="EntirePool" numberOfSharedPoolPartitions="0" numberOfUnsharedPoolPartitions="0" numberOfFreePoolPartitions="0" freePoolDistributionTableSize="1" surgeThreshold="-1" surgeCreationInterval="0" testConnection="false" testConnectionInterval="0" stuckTimerTime="0" stuckTime="0" stuckThreshold="0" />
修改属性直接用 AdminConfg.modify 命令即可:
wsadmin>attrs = '[[maxConnections 150] [minConnections 30]]' wsadmin>AdminConfig.modify(connection, attrs)
修改后可以用 AdminConfig.showall() 或者 AdminConfig.showAttribute() 命令核对一下属性是否修改成功:
wsadmin>AdminConfig.showAttribute(connection, 'maxConnections') '150' wsadmin>AdminConfig.showAttribute(connection, 'minConnections') '30'
最后别忘了用 AdminConfig.save() 命令保存修改。
通过以上实例读者应该可以了解掌握了查找定位一个 WAS 资源对象的方法,下面我们再介绍两个针对其它类型资源的实例来巩固一下定位资源的方法。
实例 2.在 server1 上添加一个 Java 虚拟机的定制属性
本例是在做客户服务时,客户的脚本开发人员提出的一个需求,如何在管理控制台上完成此操作,请参考 WAS 6.1 信息管理中心的 在 WebSphere Application Server 中配置 JVM 定制属性、过滤 HTTP 请求和启用 SPNEGO TAI 文档。 这里我们只需创建 com.ibm.ws.security.spnego.isEnabled=true
属性:
图 7.Java 虚拟机定制属性
按照上文所描述的方法,我们首先要定位属性所在的配置文件,根据前面总结的资源分类表,显然这个属性是在 server1 的配置管理文件里,也就是 server1 目录下的 server.xml。在我们熟悉这个流程后,可以简化查看修改文件的步骤,直接去目录下找到该文件并备份为后面文件比较做准备。因此,用户在管理控制台上添加完“com.ibm.ws.security.spnego.isEnabled=true
”的属性后可直接可以点击保存按钮。把更新后的 server.xml 文件和先前保存的文件进行比较,会发现更新后的文件在 JavaVirtualMachine 对象下多了一个属性对象(如清单 5 所示)
清单 5.资源配置文件中的 Java 虚拟机对象
<jvmEntries xmi:id="JavaVirtualMachine_1227446191404" verboseModeClass="false" verboseModeGarbageCollection="false" verboseModeJNI="false" initialHeapSize="512" maximumHeapSize="2048" runHProf="false" debugMode="false" debugArgs="-Djava.compiler=NONE -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket, server=y,suspend=n,address=7777" disableJIT="false"> <systemProperties xmi:id="Property_1227771753888" name="com.ibm.ws.security.spnego.SpnegoFilter" value="true" required="false"/> </jvmEntries>
这个就是我们要通过脚本去创建的属性。值得注意的是,这个属性和 JavaVirtualMachine 类型所带的简单属性(比如 initialHeapSize="512")不同,我们要创建的属性其实也是一个对象,只不过是 Property 类型的对象,真正的属性是 Property 对象中“name”和“value”的简单属性。从上面 xml 文件片段,我们还可以看到,除了“name”和“value”简单属性外,还有一个“required”属性,这个属性在手工用管理控制台添加时并未出现,该属性是自动添加上的,默认值是“false”。我们在用脚本添加时需要在代码中指定。下面我们先要确定Property 的父对象 JavaVirtualMachine 的配置标识,按照实例一所描述的方法,可以用 XML 编辑器明确对象间的层次关系:
<process:Server xmi:id="Server_1227446191404" name="server1"…> <processDefinitions xmi:type="processexec:JavaProcessDef"…> <jvmEntries xmi:id="JavaVirtualMachine_1227446191404"…>
通过 AdminConfig.getid() 命令,得到 JavaVirtualMachine 的配置标识:
wsadmin>AdminConfig.getid(' /Cell:/Node:/Server:server1/JavaProcessDef:/JavaVirtualMachine:/') '(cells/cuixx02Cell01/nodes/cuixx02Node04/servers/server1| server.xml#JavaVirtualMachine_1227446191404)' 用 AdminConfig.create() 命令创建 Property 对象:
清单 6.创建Java虚拟机对象属性
wsadmin>jvm = AdminConfig.getid('/Cell:/Node:/Server:server1/JavaProcessDef:/JavaVirtualMachine:/') wsadmin>attrs = '[[name com.ibm.ws.security.spnego.isEnabled][value true][required false]]' wsadmin>AdminConfig.create('Property', jvm, attrs)'com.ibm.ws.security.spnego.isEnabled( cells/cuixx02Cell01/nodes/cuixx02Node04/serrvers/server1| server.xml#Property_1227775684170)'
我们来检查一下创建的位置和属性值是否都正确,可以用 AdminConfig.getid() 命令直接尝试去找到这个属性对象的配置标识:
wsadmin>prop = AdminConfig.getid('/Cell:/Node:/Server:server1/JavaProcessDef: /JavaVirtualMachine:/Property:com.ibm.ws.security.spnego.isEnabled/')
最后我们用 AdminConfig.showall() 命令查看一下属性值:
wsadmin>print AdminConfig.showall(prop) [name com.ibm.ws.security.spnego.isEnabled] [required false] [value true]
通过上面两个实例,读者应该已经掌握了如何先在管理控制台上进行操作,然后通过比较新旧文件的方法来定位一个 WAS 的资源的具体位置。在此方法的基础上,如果对配置储藏室的目录结构及 XML 文件里对象的层次结构比较熟悉了,在很多时候我们可以简化这个方法,不用再在管理控制台上完全重复一遍操作,而可以通过仔细观察配置文件来直接编写脚本命令。
实例 3.添加一个信任关联的拦截器
虽然我们在此例中会简化一些步骤,但是整个流程还是要遵循上面所介绍的方法。所以,第一步我们还是要先确定所添加的拦截器对象在 WAS 配置储藏室中的文件路径。通过在 WAS 信息中心中查询拦截器关键字(英文是 TAInterceptor),我们可以知道此对象为安全机制里的一个对象。所以,很显然,它应该存储在 Cell 级别下的 security.xml 文件中。
第二步,我们再来确定此对象在xml文件中的具体位置。这个也很简单,通过在 security.xml 文件中搜索拦截器的对象名称(TAInterceptor),我们可以找到已经存在的拦截器对象,并以此分析出对象的层次关系 (如清单 7 所示):
清单 7.拦截器对象在资源配置文件中的层次结构
<security:Security xmi:version="2.0"…> <authMechanisms xmi:type="security:LTPA"…> <trustAssociation xmi:id="TrustAssociation_1" enabled="false"> <interceptors xmi:id="TAInterceptor_1"…>
第三步就是用AdminConfig.getid()命令确定拦截器的父对象(TrustAssociation)的配置标识:
wsadmin>AdminConfig.getid('/Security:/LTPA:/TrustAssociation:/') '(cells/cuixx02Cell01|security.xml#TrustAssociation_1)'
最后一步就是要创建拦截器对象了,参照已有的对象,我们可以知道创建此对象所必须的属性名是“interceptorClassName”:
<interceptors xmi:id="TAInterceptor_1" interceptorClassName="com.ibm.ws.security.web.WebSealTrustAssociationInterceptor" />
当然,如果不能很确定,也该可以通过 AdminConfig.required() 命令来得到创建对象所需的必要属性:
wsadmin>print AdminConfig.required('TAInterceptor') Attribute Type interceptorClassName String
好,现在对父对象的配置标识和对象所需属性都已经确定了,我们就可以用如下命令创建拦截器对象了:
清单 8.创建拦截器对象
wsadmin>attrs = '[[interceptorClassName com.ibm.ws.security.web.TAMTrustAssociationInterceptorPlus]]' wsadmin>trust = AdminConfig.getid('/Security:/LTPA:/TrustAssociation:/') wsadmin>AdminConfig.create('TAInterceptor', trust, attrs) '(cells/cuixx02Cell01|security.xml#TAInterceptor_1227896367526)'