WAS管理编程常用技巧.docx
《WAS管理编程常用技巧.docx》由会员分享,可在线阅读,更多相关《WAS管理编程常用技巧.docx(14页珍藏版)》请在冰豆网上搜索。
WAS管理编程常用技巧
WebSphereApplicationServer管理编程简述
WebSphereApplicationServer(以下简称为WAS)提供了两种管理途径:
基于Web式的管理控制台和基于命令行式的wsadmin工具;
还可以通过管理编程接口(WebSphereManagementAPI)来开发符合特定需求的管理应用
WAS的管理体系是基于JMX规的,JMX规定义了三层结构:
Distributedlayer:
包含各种适配器,使得使用不同协议(如RMI,HTTP)的管理应用能访问代理层。
Agentlayer:
包含MbeanServer,是Mbean的注册中心,操纵各种Mbean并对外提供各种管理服务,如监控,定时任务,Mbean的动态加载等。
Instrumentationlayer:
包含各种Mbean,Mbean实现对资源的访问和代表了资源状态。
图1.JMX规的三层结构示例
JMX即JavaManagementExtensionsJava管理扩展
MBean即managedbeans被管理的Beans
一个MBean是一个被管理的Java对象,有点类似于JavaBean,一个设备、一个应用或者任资源都可以被表示为MBean,MBean会暴露一个接口对外,这个接口可以读取或者写入一些对象中的属性,通常一个MBean需要定义一个接口,以MBean结尾,例如:
EchoMBean,格式为XXXMBean,这个是规,必须得遵守。
描述一个可管理的资源。
是一个java对象,遵循以下一些规则:
1.必须是公用的,非抽象的类
2.必须有至少一个公用的构造器
3.必须实现它自己的相应的MBean接口或者实现javax.management.DynamicMBean接口
4.可选的,一个MBean可以实现javax.management.NotificationBroadcaster接口MBean的类型。
WAS的管理体系,如图-2所示:
图2.WAS的管理体系
本文主要介绍上图中customclient的编程。
管理编程分为下面两种途径:
1.直接调用Mbean
2.使用WAS的管理编程接口
WebSphereJMXMbeans
Mbeans介绍
WAS提供了各种类型的Mbean,封装了各种管理功能,如对WAS系统环境,J2EE应用,J2EE资源等的管理和监控。
获得某个Mbean:
每个MBean都有一个ObjectName,在使用该MBean之前必须先找到它。
ObjectName可以通过AdminClient,以格式化的查询串进行查询。
格式化的查询串可以选择性地包括以下的特性:
域名、节点名、进程名、类型、名称等等。
一个查询串既可惟一标识单个ObjectName,也可以代表多个具有公共特性的ObjectName。
MBean通常是以它们的类型进行分类的。
一些MBean类型(例如Perf)会在应用服务器中提供单个的实例,但其他MBean类型(例如servlet和EJB)会在应用服务器中提供多个实例。
清单1.获得某个server上的类型为JVM的MBean
Stringquery=“*:
type=JVM,process=server1,node=node1,*"”;
queryName=newObjectName(query);
SetmBeans=null;
try{
mBeans=adminClient.queryNames(queryName,null);
}catch(ConnectorExceptione){
e.printStackTrace();
}
我们也可以基于JMXconnectorspecification和JMXRemoteapplicationprogramminginterface(API)(JSR160)来访问Mbean。
参见WAS信息中心文章“CreateaJMXremoteclientprogrambyusingtheJMXremoteAPI”。
在一个WASNetworkDeployment环境中,我们可以通过AdminClient连接到dmgr,也可以直接去连接某个nodeagent或server。
如果我们连接的是dmgr,那么通过dmgr去访问nodeagent和server上的MBean时,前提条件是这个nodeagent或server必须是启动的。
访问Mbean的属性和法
我们知道,调用EJB或Webservice最终都要通过Java接口来进行,但Mbean却不同。
调用Mbean的法与java反射机制类似,要提供法名称,法的参数类型,最后才能invoke该法。
访问Mbean的普通属性:
清单2.访问Mbean的普通属性
Objectheapsize=adminClient.getAttribute(mbean,"heapSize");
调用Mbean的法:
清单3.调用Mbean的法
ObjectNamejvmBean=MBeanFactory.getInstance().getJVMMBean
(server.nodeName,server.serverName);
Stringsignature[]={"java.lang.String"};
server.hostIP=(String)adminClient.invoke(jvmBean,"getIPAddress",
newObject[]{server.hostName},signature);
WebSpheremanagementAPI
WAS提供的管理编程接口包含在以.ibm.websphere.management开头的包中。
下面介绍一下包中的实用API。
AdminClient和AdminService
AdminClient用于连接远程的JVM,AdminService用于连接本地JVM,如果你的管理代码运行在和被管理的服务器相同的JVM,那可以使用AdminService接口。
AdminService具有和AdminClient类似的法,也能访问服务器上的Mbean。
下面是获得AdminClient接口的代码:
清单4.获得AdminClient接口的代码
Propertiesprops=newProperties();
props.put(AdminClient.CONNECTOR_TYPE,AdminClient.CONNECTOR_TYPE_SOAP);
props.put(AdminClient.CONNECTOR_HOST,host.getHostIP());
props.put(AdminClient.CONNECTOR_PORT,host.getSoapport());
props.put(AdminClient.CONNECTOR_AUTO_ACCEPT_SIGNER,true);
if(isSecurityEnabled()){
props.setProperty(AdminClient.CONNECTOR_SECURITY_ENABLED,Boolean.toString(true));
props.setProperty(AdminClient.USERNAME,host.getUsername());
props.setProperty(AdminClient.PASSWORD,host.getPasswd());
}
AdminClient既可以运行在adminthinclient中,也可以运行在WASserverruntime中。
获得AdminService接口:
清单5.获得AdminService接口的代码
AdminServiceadminService=AdminServiceFactory.getAdminService();
WsadminAPI和managementAPI之间的对应关系
WAS命令行脚本工具提供了几个管理对象AdminApp,AdminTask,AdminConfig,AdminControl。
它们分别对应不同的管理API:
1.AdminApp:
AdminApp对象的功能对应于两个包.ibm.websphere.management.application和.ibm.websphere.management.application.client。
通过这两个包下面的API,我们可以安装/卸载,启动/停止一个J2EE应用。
和应用管理相关的编程比较固定,本文没有过多介绍这些API的使用,读者可以参考本文提供的例子ApplicationMgr.java,里面包含了应用安装和启停的示例。
2.AdminControl:
AdminControl汇集了一些常用的Mbean的功能,如ServerMbean。
此外,它能直接调用任一个Mbean对象。
所以,AdminControl提供的功能可以由AdminClient/AdminService来替换。
3.AdminConfig:
AdminConfig对象对应于两个包.ibm.websphere.management.configservice和.ibm.websphere.management.configservice.tasks。
4.AdminTask:
AdminTask对象对应于两个包.ibm.websphere.management.cmdframework和.ibm.websphere.management.cmdframework.provider。
本文主要介绍AdminConfig和AdminTask对应的管理编程。
使用ConfigService
WAS的配置信息有些可以通过Mbean去获得,如cell/node/server的名称,也可以通过ConfigServer去获取。
而有些配置信息只能通过ConfigService去获得。
下面是使用ConfigService时会遇到的几个概念:
ConfigData:
configdata对应于config目录下的某个xml文件或xml文件的某个片段,通过操纵configdata,就可以读写该xml文件。
ConfigType:
configdata的类型。
首先要知道你要访问配置信息的类型才能去访问。
通过configService的getSupportedConfigObjectTypes()法可以获得所有的ConfigData的类型信息。
例如我们要获得WAS上所有的数据源的配置信息,通过查找上述类型列表,可以知道数据源的ConfigType为DataSource。
ConfigDataId:
ConfigData的唯一标识。
如访问某个ConfigData?
通过ConfigDatatype来查询ConfigData
通过ConfigDataId来创建ConfigData
ConfigData和ConfigDataId的关系如下:
清单6.ConfigData和ConfigDataId的转换关系
//获得ConfigData的ConfigDataId
ConfigDataIdconfigDataId=ConfigServiceHelper.getConfigDataId(configData);
//已知ConfigDataId,得到其ConfigData
publicObjectNamecreateConfigData(StringdataId){
ObjectNameconfigData=null;
ConfigDataIdid=newConfigDataId(dataId);
configData=ConfigServiceHelper.createObjectName(id);
returnconfigData;
}
使用ConfigService获得环境信息
下面举例说明如用MBean和ConfigService获取集群信息,便读者的对比。
关于更多其它环境信息的获取,读者可以参考本文例子WASEnvHelper.java。
清单7.通过MBean获得所有集群及集群成员
publicvoidlistClusterMembersFromMBean(){
Setclusters=queryMBeanList("WebSphere:
type=Cluster,*");
Iteratorci=clusters.iterator();
Stringsignature[]={"java.lang.String"};
while(ci.hasNext()){
ObjectNamecluMBean=(ObjectName)ci.next();
try{
Stringclustername=cluMBean.getCanonicalName();
clustername=(String)adminClient.getAttribute(cluMBean,"clusterName");
System.out.println(clustername);
ClusterMemberData[]membersData=(ClusterMemberData[])adminClient.invoke(cluMBean,
"getClusterMembers",newObject[]{},signature);
for(ClusterMemberDataclusterMemberData:
membersData){
System.out.println(clusterMemberData.memberName);
}
}catch(Exceptione){
e.printStackTrace();
}
}
清单8.通过ConfigService获得所有集群及集群成员
publicHashMaplistClusterMembersFromCfg(){
HashMapmap=newHashMap();
ObjectNamepattern=ConfigServiceHelper.createObjectName(null,"ServerCluster");
try{
ObjectName[]configData=configService.queryConfigObjects(session,null,
pattern,null);
for(inti=0;iListmembers=newArrayList();
Stringclustername=(String)configService.getAttribute(session,
configData[i],"name");
List_members=(ArrayList)configService.getAttribute(
session,configData[i],"members");
for(AttributeListmember:
_members){
Stringname=(String)ConfigServiceHelper.getAttributeValue(
member,"memberName");
members.add(name);
}
map.put(clustername,members);
}
}catch(Exceptione){
e.printStackTrace();
}
returnmap;
}
创建新的配置
创建配置的难点在于确立AttributeList的结构,尤其是对于嵌套复杂的AttributeList,往往需要先写个读取的程序来判断里面每个对象的类型。
下面是创建JDBCProvider和Datasource的实例。
注意,在不同的scope下都有resources.xml,所以在查询resources.xml中的ConfigData时要先确定scope。
清单9.通过ConfigService获得所有集群及集群成员
publicvoidcreateJDBCResource(AdminClientadminClient){
Sessionsession=newSession();
ConfigServiceconfigService=null;
try{
configService=newConfigServiceProxy(adminClient);
ObjectNamescope=configService.resolve(session,"Node=kuNode05:
Server=server1")[0];
ObjectNamepattern=ConfigServiceHelper.createObjectName(null,"JDBCProvider");
ObjectName[]configData=configService.queryConfigObjects(session,scope,
pattern,null);
ObjectNameparent=configData[0];
System.out.println(parent);
AttributeListprovAttrs=newAttributeList();
provAttrs.add(newAttribute("name","MyJDBCProvider"));
provAttrs.add(newAttribute("implementationClassName","
.mycompany.MyConnectionPoolDataSource"));
provAttrs.add(newAttribute("description","ApsectJDBCdriver"));
//createtheprovider
ObjectNamejdbcProv=configService.createConfigData(session,scope,"JDBCProvider",
"JDBCProvider",provAttrs);
System.out.println("createtheJDBCprovidersuccessfully.");
configService.addElement(session,jdbcProv,"classpath","",-1);
//Preparetheattributelist
AttributeListdsAttrs=newAttributeList();
dsAttrs.add(newAttribute("name","myTestDS"));
dsAttrs.add(newAttribute("jndiName","jdbc/MyTestDS"));
//createanewdatasource
ObjectNamedataSource=configService.createConfigData(session,jdbcProv,
"DataSource","DataSource",dsAttrs);
//AddapropertySet.
AttributeListpropSetAttrs=newAttributeList();
ObjectNameresourcePropertySet=configService.createConfigData(session,dataSource,
"propertySet","",propSetAttrs);
System.out.println("createtheDataSourcesuccessfully.");
configService.save(session,false);
}catch(Exceptionex){
ex.printStackTrace();
}
}
修改已有配置
下面的updateAttributelist是一个通用的法,相对于设置好Attributelist里的值之后做一个提交。
清单10.提交更新的通用法
//设置新的属性值
ConfigServiceHelper.setAttributeValue(threadpool,"minimumSize",
newInteger((int)pool.getMinSize()));
ConfigServiceHelper.setAttributeValue(threadpool,"maximumSize",
newInteger((int)pool.getMaxSize()));
//更新整个Attributelist
updateAttributelist(threadpool);
publicvoidupdateAttributelist(AttributeListattrs){
try{
ConfigDataIdid=ConfigServiceHelper.getConfigDataId(att