IBM WebSphere Liberty 配置文件使用监视器功能来提供性能指标,该功能符合 Java®Management Extension (JMX) 标准。本教程系列将介绍如何使用 Jython 脚本,使用 REST Connector API 连接到 Liberty 服务器或 Liberty 集合体控制器来检索这些指标。在这一部分中,将通过使用 Jython 脚本收集数据。
变量和语法:在本教程中,WebSphere Liberty 配置文件安装目录是使用变量 $WLP_DIR 定义的。变量 $JAVA_DIR 用于指定 Java 安装目录。此外,必须使用以下语法来启动每个命令:
$
>>>
在本教程中,您使用了 Liberty 配置文件中提供的 REST Connector API,以便通过使用 JMX 连接到成员和控制器 Liberty 服务器,并收集性能数据。对 REST 连接器的远程访问需要使用管理员角色和安全套接字层 (SSL) ,以确保数据交换的保密性。
默认情况下,webProfile 会加载所需的所有特性,包括 restConnector-1.0
和 ssl-1.0
特性。您只需要添加监控特性。管理员角色被配置为带有 <quickStartSecurity userName="wlpadmin" userPassword="wlpadmin"/>
标记。
将 REST 连接器文件复制到 Jython 目录:
$ cd $WLP_DIR/wlp/jython $ cp $WLP_DIR/wlp/clients/jython/restConnector.py . $ cp $WLP_DIR/wlp/clients/restConnector.jar . $ ls -l
清单 1 显示了被复制的 REST 连接器文件。
-rwxr-xr-x 1 usr grp 37021723 Oct 13 16:11 jython-standalone-2.7.0.jar -rw-r--r-x 1 usr grp 223484 Oct 14 12:15 restConnector.jar -rwxr-xr-x 1 usr grp 2834 Oct 14 12:14 restConnector.py
收集性能数据涉及以下步骤:
dir(), type()
getClass(), getMethods()
mconnection.invoke( <MBean>, '<method>', ['<param1>', ...], ['<param1 type>', ...])
下面的各个小节将分别介绍每一个步骤。
启动一个交互式 Jython 会话:
$ java -cp jython-standalone-2.7.0.jar:restConnector.jar org.python.util.jython
清单 2 显示了启动 Jython 会话的结果。
Jython 2.7.0 (default:9987c746f838, Apr 29 2015, 02:25:11) [IBM J9 VM (IBM Corporation)] on java1.8.0 Type "help", "copyright", "credits" or "license" for more information. >>> >>> dir() ['__builtins__', '__doc__', '__name__', '__package__']
要连接到控制器服务器,可使用 restConnector.py 文件中的 JMXRESTConnector
对象。我们使用了以下元素,如清单 3 所示:
>>> from restConnector import JMXRESTConnector >>> JMXRESTConnector.trustStore = '../usr/servers/controller/resources/security/key.jks' >>> JMXRESTConnector.trustStorePassword = 'wlpadmin' >>> connector = JMXRESTConnector() >>> connection = connector.connect( '<controller_hostname>', 9443, 'wlpadmin', 'wlpadmin') Connecting to the server... Successfully connected to the server "<controller_hostname>:9443"
连接到控制器 MBean 服务器:
mconnection = connection.getMBeanServerConnection()
清单 4 显示了如何连接到 MBean 服务器并获得有关该连接的信息。
>>> mconnection = connector.getMBeanServerConnection() >>> mconnection com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection@aba685fb >>> dir( mconnection) ['MBeanCount', 'PollingMode', 'ServerPollingThread', '__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'addNotificationListener', 'class', 'createMBean', 'defaultDomain', 'domains', 'equals', 'getAttribute', 'getAttributes', 'getClass', 'getDefaultDomain', 'getDomains', 'getMBeanCount', 'getMBeanInfo', 'getObjectInstance', 'hashCode', 'invoke', 'isInstanceOf', 'isRegistered', 'notify', 'notifyAll', 'queryMBeans', 'queryNames', 'removeNotificationListener', 'setAttribute', 'setAttributes', 'toString', 'unregisterMBean', 'wait'] >>> type( mconnection) <type 'com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection'> >>> mconnection.getClass() <type 'com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection'> >>> for i in mconnection.getClass().getMethods(): print i ... public boolean java.lang.Object.equals(java.lang.Object) public int java.lang.Object.hashCode() public java.lang.String java.lang.Object.toString() 鈥 ?public java.util.Set com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection.queryMBeans(javax .management.ObjectName,javax.management.QueryExp) throws java.io.IOException public java.util.Set com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection.queryNames(javax.management.ObjectName,javax.management.QueryExp) throws java.io.IOException public boolean com.ibm.ws.jmx.connector.client.rest.internal.RESTMBeanServerConnection.isRegistered(java x.management.ObjectName) throws java.io.IOException ...
通过使用 Jython 中提供的内省方法( type
, dir
)或 Java 中提供的内省方法( getClass
, getMethods
),您可以看到对所有对象可用的不同属性和方法。您还可以看到传递给方法的参数(签名)。
要列出可用的 MBean,可使用清单 5 中的命令。要列出所有 MBean,可使用 queryNames
方法。要使用此方法,可向该方法传递一个 ObjectName
和一个 QueryExp
(被设置为 None
)。 ObjectName
的语法是标准的 JMX 对象名称语法:
domain:key=value,key=value,key=value,...
IBM WebSphere 拥有以下域:
WebSphere:key=value,key=value,key=value,...
>>> from javax.management import ObjectName >>> mbeans = mconnection.queryNames( ObjectName( "WebSphere:*"), None).toArray() >>> type( mbeans) <type 'array.array'> >>> mbeans[0] WebSphere:name=com.ibm.websphere.config.mbeans.FeatureListMBean >>> type( mbeans[0]) <type 'javax.management.ObjectName'> >>> for i in mbeans: print i ... WebSphere:name=com.ibm.websphere.config.mbeans.FeatureListMBean WebSphere:feature=collectiveController,type=ControllerConfig,name=ControllerConfig WebSphere:name=com.ibm.websphere.config.mbeans.ServerXMLConfigurationMBean WebSphere:type=ServletStats,name=com.ibm.ws.jmx.connector.server.rest.MBeanServerConnector WebSphere:feature=collectiveController,type=CollectiveRepository,name=CollectiveRepository WebSphere:feature=collectiveController,type=MaintenanceMode,name=MaintenanceMode WebSphere:feature=collectiveMember,type=EndpointRoutingInfo,name=EndpointRoutingInfo WebSphere:feature=collectiveController,type=RepositoryPathUtility, name=RepositoryPathUtility WebSphere:name=com.ibm.ws.jmx.mbeans.sessionManagerMBean WebSphere:name=com.ibm.ws.jmx.mbeans.generatePluginConfig WebSphere:feature=restConnector,type=FileService,name=FileService WebSphere:feature=collectiveController,type=ServerCommands,name=ServerCommands WebSphere:name=com.ibm.ws.config.serverSchemaGenerator WebSphere:feature=collectiveController,type=CollectiveRegistration, name=CollectiveRegistration WebSphere:feature=CacheAdmin,type=DynaCache,name=DistributedMap WebSphere:feature=collectiveController,type=RoutingContext,name=RoutingContext WebSphere:feature=collectiveController,type=ClusterManager,name=ClusterManager WebSphere:feature=collectiveController,type=RoutingInfoManager,name=RoutingInfoManager WebSphere:feature=collectiveController,type=RepositoryConfiguration, name=RepositoryConfiguration WebSphere:service=com.ibm.ws.kernel.filemonitor.FileNotificationMBean WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint WebSphere:type=JvmStats WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint-ssl WebSphere:name=com.ibm.websphere.runtime.update.RuntimeUpdateNotificationMBean WebSphere:feature=collectiveController,type=AdminMetadataManager,name=AdminMetadataManager WebSphere:feature=collectiveMember,type=SingletonServiceMessenger, name=SingletonServiceMessenger WebSphere:feature=kernel,name=ServerInfo WebSphere:type=ThreadPoolStats,name=Default Executor WebSphere:feature=restConnector,type=FileTransfer,name=FileTransfer
获得 JvmStats
MBean,如清单 6 所示。
>>> mbeans = mconnection.queryNames( ObjectName( "WebSphere:type=JvmStats,*"), None).toArray() >>> for i in mbeans: print i ... WebSphere:type=JvmStats
然后,通过使用 getMBeanInfo
方法,可以查看 JvmStats
MBean 的详细信息,如清单 7 所示。
>>> mbean_jvm = mbeans[ 0] >>> mbean_info = mconnection.getMBeanInfo( mbean_jvm) >>> type( mbean_info) <type 'javax.management.MBeanInfo'> >>> dir( mbean_info) ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'attributes', 'class', 'className', 'clone', 'constructors', 'description', 'descriptor', 'equals', 'getAttributes', 'getClass', 'getClassName', 'getConstructors', 'getDescription', 'getDescriptor', 'getNotifications', 'getOperations', 'hashCode', 'notifications', 'notify', 'notifyAll', 'operations', 'toString', 'wait'] >>> mbean_info javax.management.MBeanInfo[description=Information on the management interface of the MBean, attributes=[javax.management.MBeanAttributeInfo[description=UsedMemory, name=UsedMemory, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}], javax.management.MBeanAttributeInfo[description=FreeMemory, name=FreeMemory, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}], javax.management.MBeanAttributeInfo[description=Heap, name=Heap, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}], javax.management.MBeanAttributeInfo[description=UpTime, name=UpTime, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}], javax.management.MBeanAttributeInfo[description=ProcessCPU, name=ProcessCPU, type=double, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Double), originalType=double}], javax.management.MBeanAttributeInfo[description=GcCount, name=GcCount, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}], javax.management.MBeanAttributeInfo[description=GcTime, name=GcTime, type=long, read-only, descriptor={openType=javax.management.openmbean.SimpleType(name=java.lang.Long), originalType=long}]], constructors=[javax.management.MBeanConstructorInfo[description=Public constructor of the MBean, name=com.ibm.ws.monitors.helper.JvmStats, signature=[javax.management.MBeanParameterInfo[description=, name=p1, type=com.ibm.ws.monitors.helper.JvmMonitorHelper, descriptor={}]], descriptor={}]], operations=[], notifications=[], descriptor={immutableInfo=true, interfaceClassName=com.ibm.websphere.monitor.meters.JvmMXBean, mxbean=true}]
要获得 JvmStats
MBean 的属性,可以使用 mbean_info.
getAttributes
和 MBean 服务器的 getAttribute
方法,如清单 8 所示。
>>> mbean_attributes = mbean_info.getAttributes() >>> type( mbean_attributes) <type 'array.array'> >>> type( mbean_attributes[ 0]) <type 'javax.management.MBeanAttributeInfo'> >>> dir( mbean_attributes[0]) ['__class__', '__copy__', '__deepcopy__', '__delattr__', '__doc__', '__ensure_finalizer__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', '__subclasshook__', '__unicode__', 'class', 'clone', 'description', 'descriptor', 'equals', 'getClass', 'getDescription', 'getDescriptor', 'getName', 'getType', 'hashCode', 'is', 'isIs', 'isReadable', 'isWritable', 'name', 'notify', 'notifyAll', 'readable', 'toString', 'type', 'wait', 'writable'] >>> for attribute in mbean_attributes: name = attribute.getName() value = mconnection.getAttribute( mbean_jvm, name) type = attribute.getType() print " %s [%s] = %s" % ( name, type, str( value)) ... UsedMemory [long] = 52011592 FreeMemory [long] = 3481008 Heap [long] = 55771136 UpTime [long] = 2435005 ProcessCPU [double] = 0.0729284201396 GcCount [long] = 144 GcTime [long] = 365 >>> exit()
您刚刚使用一个 Jython 交互式会话收集了性能监控基础架构 (PMI) 数据。接下来,要添加一些 Jython 实用工具函数来简化此过程。
为了简化 Jython 会话,您可以创建一个连接参数文件和一些实用工具函数。
要创建连接参数文件,请输入:
$ vi wlp_collect_conf.py
清单 9 显示了文件的内容,您必须使用您的控制器的主机名称替换其中的 <controller_hostname> 变量。
Config = { 'host': '<controller_hostname>', 'port': 9443, 'user': 'wlpadmin', 'password': 'wlpadmin', 'truststore': '../usr/servers/controller/resources/security/key.jks', 'truststore_password': 'wlpadmin', 'objectName': 'WebSphere:*', 'collectiveName': 'WebSphere:type=CollectiveRepository,*', 'routingName': 'WebSphere:type=RoutingContext,*', 'attributeName': '*' }
现在,创建包含用于 connect
、 disconnect
和 collect
实用工具的函数的文件:
$ vi wlp_collect.py
collect
函数使用了 MBean getAttributes
和 getOperations
方法。
文件的内容必须与清单 10 中所示内容相同。在这个文件中,您必须使用您的控制器的主机名称替换 <controller_hostname> 变量。
import sys from restConnector import JMXRESTConnector from javax.management import ObjectName from wlp_collect_conf import Config def connect(): """ param : none BUT uses the Config object define in wlp_collect_conf.py result: return a connection object note : use simple connect method """ print Config[ 'port'] print Config[ 'truststore'] JMXRESTConnector.trustStore = Config['truststore'] JMXRESTConnector.trustStorePassword = Config[ 'truststore_password'] connector = JMXRESTConnector() connector.connect( Config[ 'host'], Config[ 'port'], Config[ 'user'], Config[ 'password']) return connector def disconnect( connector): """ param : a connection object (return by connect()) result: none """ connector.disconnect() def collect( connector, details = False, objectName = Config[ 'objectName'], attributeName = Config[ 'attributeName']): """ param1: connection object (return by connect() function) param2: output with or without details (True|False) param3: mbean object like "WebSphere:type=JvmStats,*" param4: attribute to retrieve in the mbean object result: return an array of mbeans objects found """ mconnection = connector.getMBeanServerConnection() # print dir( mconnection) # "WebSphere:type=endpoint,*" mbeans = mconnection.queryNames( ObjectName( objectName), None).toArray() for mbean in mbeans: print "/n MBean details for %s" % str( mbean) # --- get MBeanInfo mbean_info = mconnection.getMBeanInfo( mbean) mbean_class = mbean_info.className # --- printing attributes mbean_attributes = mbean_info.getAttributes() print "/n %s attributes" % str( len( mbean_info.attributes)) for attribute in mbean_attributes: name = attribute.name value = mconnection.getAttribute( mbean, name) type = attribute.type if details and (attributeName == "*" or attributeName == name): print " %s [%s] = %s" % ( name, type, str( value)) # --- printing operations mbean_operations = mbean_info.getOperations() print "/n %s operations" % str( len( mbean_info.operations)) for operation in mbean_operations: name = operation.getName() # value = mconnection.getOperation( mbean, name) # type = operation.type if details and (attributeName == "*" or attributeName == name): # print " %s" % name print("/n " + str( operation.getName()) + " : " + str( operation.getDescription())) for param in operation.getSignature(): print(" " + str( param.getName()) + " [" + str( param.getType()) + "] : " + str( param.getDescription())) return mbeans
collect
方法可以包含 1-4 个参数:
False
。) WebSphere:*
。) *
。) 要使用新实用工具函数,可启动一个 Jython 会话:
$ java -cp jython-standalone-2.7.0.jar:restConnector.jar org.python.util.jython
清单 11 展示了如何使用新的实用工具函数。
>>> from wlp_collect import * >>> dir() ['ClientProvider', 'Config', 'ConnectorSettings', 'JMXConnector', 'JMXRESTConnector', 'ObjectName', '__builtins__', '__doc__', '__name__', '__package__', 'array', 'collect', 'collect_controller', 'connect', 'connect_adv', 'disconnect', 'getServersFromRepository', 'java', 'print_usage', 'script_name', 'sys', 'urllib2'] >>> connection = connect() 9443 ../usr/servers/controller/resources/security/key.jks Connecting to the server... Successfully connected to the server "<controller_hostname>:9443" >>> collect( connection, False, "WebSphere:type=JvmStats,*") MBean details for WebSphere:type=JvmStats 7 attributes 0 operations array(java.lang.Object, [WebSphere:type=JvmStats]) >>> collect( connection, True, "WebSphere:type=JvmStats,*") MBean details for WebSphere:type=JvmStats 7 attributes UsedMemory [long] = 50492936 FreeMemory [long] = 11909624 Heap [long] = 62586880 UpTime [long] = 7060539 ProcessCPU [double] = 0.131003185929 GcCount [long] = 193 GcTime [long] = 460 0 operations array(java.lang.Object, [WebSphere:type=JvmStats]) >>> collect( connection, True, "WebSphere:type=JvmStats,*", 'FreeMemory') MBean details for WebSphere:type=JvmStats 7 attributes FreeMemory [long] = 23083576 0 operations array(java.lang.Object, [WebSphere:type=JvmStats]) >>> disconnect( connection)
现在,您已经通过连接到目标 Liberty 配置文件服务器并使用实用工具函数收集了性能数据。
接下来,通过仅连接到控制器,收集附加到集合体控制器的任何 Liberty 成员的性能数据。您将使用两个 MBean:
该控制器维护着所附加的 Liberty 服务器成员的一个存储库。该存储库有一个始于根元素 ( /
) 的树型结构。您可以通过使用 Jython 来浏览该存储库。清单 12 显示了如何获得 collectiveRepository
MBean 并列出了它的所有方法。
>>> connection = connect() 9443 ../usr/servers/controller/resources/security/key.jks Connecting to the server... Successfully connected to the server "<controller_hostname>:9443" >>> mbeans = collect( connection) MBean details for WebSphere:name=com.ibm.websphere.config.mbeans.FeatureListMBean 0 attributes 1 operations MBean details for WebSphere:feature=collectiveController,type=ControllerConfig,name=ControllerConfig 0 attributes 3 operations 鈥 ? >>> for i in mbeans: print i ... WebSphere:name=com.ibm.websphere.config.mbeans.FeatureListMBean WebSphere:feature=collectiveController,type=ControllerConfig,name=ControllerConfig WebSphere:name=com.ibm.websphere.config.mbeans.ServerXMLConfigurationMBean WebSphere:type=ServletStats,name=com.ibm.ws.jmx.connector.server.rest.MBeanServerConnector WebSphere:feature=collectiveController,type=CollectiveRepository,name=CollectiveRepository WebSphere:feature=collectiveController,type=MaintenanceMode,name=MaintenanceMode WebSphere:feature=collectiveMember,type=EndpointRoutingInfo,name=EndpointRoutingInfo WebSphere:feature=collectiveController,type=RepositoryPathUtility, name=RepositoryPathUtility WebSphere:name=com.ibm.ws.jmx.mbeans.sessionManagerMBean WebSphere:name=com.ibm.ws.jmx.mbeans.generatePluginConfig WebSphere:feature=restConnector,type=FileService,name=FileService WebSphere:feature=collectiveController,type=ServerCommands,name=ServerCommands WebSphere:name=com.ibm.ws.config.serverSchemaGenerator WebSphere:feature=collectiveController,type=CollectiveRegistration, name=CollectiveRegistration WebSphere:feature=CacheAdmin,type=DynaCache,name=DistributedMap WebSphere:feature=collectiveController,type=RoutingContext,name=RoutingContext WebSphere:feature=collectiveController,type=ClusterManager,name=ClusterManager WebSphere:feature=collectiveController,type=RoutingInfoManager,name=RoutingInfoManager WebSphere:feature=collectiveController,type=RepositoryConfiguration, name=RepositoryConfiguration WebSphere:service=com.ibm.ws.kernel.filemonitor.FileNotificationMBean WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint WebSphere:type=JvmStats WebSphere:feature=channelfw,type=endpoint,name=defaultHttpEndpoint-ssl WebSphere:name=com.ibm.websphere.runtime.update.RuntimeUpdateNotificationMBean WebSphere:feature=collectiveController,type=AdminMetadataManager,name=AdminMetadataManager WebSphere:feature=collectiveMember,type=SingletonServiceMessenger, name=SingletonServiceMessenger WebSphere:feature=kernel,name=ServerInfo WebSphere:type=ThreadPoolStats,name=Default Executor WebSphere:feature=restConnector,type=FileTransfer,name=FileTransfer >>> mbeans_repo = collect( connection, True, "WebSphere:type=CollectiveRepository,*") MBean details for WebSphere:feature=collectiveController,type=CollectiveRepository,name=CollectiveRepository 0 attributes 13 operations create : Creates a new Node with the specified nodeName in the repository. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". data [java.lang.Object] : The data to store in the Node, null is supported. delete : Deletes the specified Node and all nodes under it. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". exists : Indicates whether or not the specified Node exists. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". getData : Retrieves the data stored in the specified Node. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". getDescendantData : Retrieves the data stored in the specified Node and the data of all of its descendants. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". setData : Stores data in the specified Node. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". data [java.lang.Object] : The data to store in the Node, null is supported. getChildren : Returns a collection of the names of the children Nodes of the specified Node. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". absolutePath [boolean] : True if the returned collection should contain fully qualified node names. registerMember : Registers this member with the repository and starts the repository monitoring of this member. heartBeatInterval [int] : The heart beat interval, in seconds, for this member. memberData [java.util.Map] : Provides data unique to this member; null may be provided if no data is required deregisterMember : Instructs the repository to unregister the specified member and discard any active repository services presently associated with the member. memberId [java.lang.String] : The member unregistering with the repository. sendHeartBeat : Sends a heart beat for the specified member to the repository. memberId [java.lang.String] : The member identifier to which the heart beat belongs. sendHeartBeat : Sends a heart beat for the specified member to the repository and allows the member to specify a new heart beat interval. memberId [java.lang.String] : The member identifier to which the heart beat belongs. newHeartBeatInterval [int] : The new heart beat interval, in seconds, for this member. dump : Writes the content of the specified Node to a file or the server log. nodeName [java.lang.String] : The fully qualified Node name, starting from the root "/". fileName [java.lang.String] : The file to dump the content to. Default to server log if null or empty. correlator [java.lang.String] : An optional string to identify the dump. It will be the first line of the dump if not null or empty. retrieveMemberRootCertificate : Unknown operation
通过使用 c
ollectiveRepository
MBean 对象,您可以获得一些内容和成员,如清单 13 所示。
>>> mconnection = connection.getMBeanServerConnection() >>> repo_content = mconnection.invoke( mbeans_repo[0], 'getDescendantData', [ '/'], [ 'java.lang.String']) >>> for content in repo_content: print content ... / /sys.was.system /sys.was.collectives /sys.was.system/atlas /sys.was.collectives/local /sys.was.system/atlas/members /sys.was.system/atlas/replicas /sys.was.collectives/local/collective.uuid /sys.was.collectives/local/hosts /sys.was.collectives/local/adminCenter-1.0 /sys.was.collectives/local/collective.name 鈥 ? >>> mconnection.invoke( mbeans_repo[0], 'getChildren', ['/sys.was.collectives/local/hosts', False], ['java.lang.String', 'boolean']) [<controller_hostname>, <server1_hostname>]
定义一个实用工具函数来列出集合体成员,如清单 14 所示。请注意,可以使用 urllib2
模块来解码路径。
import urllib2 def getServersFromRepository( connection, repository_mbean): """ param1: connection (return by connect() function) param2: mbean of the repository (return by collect( connection, [False|True], "WebSphere:type=CollectiveRepository,*") result: return the servers members defined in this repository """ results = [] mconn = connection.getMBeanServerConnection() # --- get hosts: [10.151.27.202, localhost] hosts = mconn.invoke( repository_mbean, 'getChildren', ['/sys.was.collectives/local/hosts', False], ['java.lang.String', 'boolean']) # --- get userdirs for each host: [C%3A%2FIBM%2Fwlp_web%2Fusr] for host in hosts: print "/nhost: " + host userdirs = mconn.invoke( repository_mbean, 'getChildren', ['/sys.was.collectives/local/hosts/%s/userdirs' % host, False], ['java.lang.String', 'boolean']) for userdir in userdirs: print " userdir: " + str( urllib2.unquote( userdir)) # --- get servers for this userdir: [controller, server1] servers = mconn.invoke( repository_mbean, 'getChildren', ['/sys.was.collectives/local/hosts/%s/userdirs/%s/servers' % ( host, userdir), False], ['java.lang.String', 'boolean']) for server in servers: print " server: " + server results.append( {'host': host, 'userdir': userdir, 'server': server}) return results
通过使用您刚刚在清单 14 中定义的实用工具函数来显示集合体存储库。清单 15 显示了 collectiveRepository 的内容。
>>> getServersFromRepository( connection, mbeans_repo[ 0]) host: <server1_hostname> userdir: $WLP_DIR/wlp/usr server: server1 host: <controller_hostname> userdir: $WLP_DIR/wlp/usr server: controller [{'server': u'server1', 'host': u'<server1_hostname>', 'userdir': u'$WLP_DIR%2Fwlp%2Fusr'}, {'server': u'controller', 'host': u'<controller_hostname>', 'userdir': u'$WLP_DIR%2Fwlp%2Fusr'}]
现在,您已经有了集合体成员的名单,您可以使用 RoutingContext
MBean 对象将您的请求重定向到每个成员。
现在,您可以连接到 Liberty 服务器,然后收集该服务器的性能数据。如果该服务器是一个控制器,那么您可以列出每个集合体成员。要通过使用控制器来收集来自这些成员的性能数据,可以使用控制器的 RoutingContext
MBean。
清单 16 显示了如何获得 RoutingContext
MBean 的属性和方法。
>>> collect( connection, True, "WebSphere:type=RoutingContext,*") MBean details for WebSphere:feature=collectiveController,type=RoutingContext,name=RoutingContext 0 attributes 2 operations assignServerContext: Operation exposed for management hostName [java.lang.String] : userDir [java.lang.String] : serverName [java.lang.String] : assignHostContext: Operation exposed for management hostName [java.lang.String] : array(java.lang.Object, [WebSphere:feature=collectiveController,type=RoutingContext,name=RoutingContext])
如清单 17 中所示,编写从集合体控制器中收集数据的实用工具函数。
>>> def collect_controller( connector, details = False, objectName = Config[ 'objectName'], attributeName = Config[ 'attributeName']): """ param1: connection object (return by connect() function) param2: output with or without details (True|False) param3: mbean object like "WebSphere:type=JvmStats,*" param4: attribute to retrieve in the mbean object result: return an array of mbeans objects found note : try to loop through all the servers members found if there is a CollectiveRepository """ mbeans = [] mconnection = connector.getMBeanServerConnection() # --- look for a CollectiveRepository mbeans_repo = mconnection.queryNames( ObjectName( Config[ 'collectiveName']), None).toArray() mbeans_rout = mconnection.queryNames( ObjectName( Config[ 'routingName']), None).toArray() if len( mbeans_repo) > 0: for mbean_repo in mbeans_repo: # --- for each repo, collect data for each members servers = getServersFromRepository( connector, mbean_repo) for mbean_rout in mbeans_rout: for server in servers: routing_context = mconnection.invoke( mbean_rout, 'assignServerContext', [ server[ 'host'], str( urllib2.unquote( server[ 'userdir'])), server[ 'server']], ['java.lang.String', 'java.lang.String', 'java.lang.String']) print("/n# --- collecting for %s:%s:%s" % ( server[ 'host'], server[ 'userdir'], server[ 'server'])) print " routing_context: " + str( routing_context) results = collect( connector, details, objectName, attributeName) mbeans.append( results) return mbeans else: print "No CollectiveRepository found..."
现在,您已经定义了所有实用工具函数。清单 18 展示了如何使用实用工具函数从集合体控制器成员数据中收集数据。
>>> servers_info = collect_controller( connection, True, "WebSphere:name=ServerInfo,*") host: <server1_hostname> userdir: $WLP_DIR/wlp/usr server: server1 host: <controller_hostname> userdir: $WLP_DIR/wlp/usr server: controller # --- collecting for <server1_hostname>:$WLP_DIR%2Fwlp%2Fusr:server1 routing_context: True MBean details for WebSphere:feature=kernel,name=ServerInfo 4 attributes DefaultHostname [java.lang.String] = <server1_hostname> UserDirectory [java.lang.String] = $WLP_DIR/wlp/usr/ InstallDirectory [java.lang.String] = $WLP_DIR/wlp/ Name [java.lang.String] = server1 0 operations # --- collecting for <controller_hostname>:$WLP_DIR%2Fwlp%2Fusr:controller routing_context: True MBean details for WebSphere:feature=kernel,name=ServerInfo 4 attributes DefaultHostname [java.lang.String] = <controller_hostname> UserDirectory [java.lang.String] = $WLP_DIR/wlp/usr/ InstallDirectory [java.lang.String] = $WLP_DIR/wlp/ Name [java.lang.String] = controller 0 operations
使用最后一个实用工具函数从集合体控制器中获得 PMI 数据,如清单 19 所示。
>>> servers_jvmstats = collect_controller( connection, True, "WebSphere:type=JvmStats,*") No CollectiveRepository found... >>> connection.disconnect() >>> connection = connect() 9443 ../usr/servers/controller/resources/security/key.jks Connecting to the server... Successfully connected to the server "<controller_hostname>:9443" >>> servers_jvmstats = collect_controller( connection, True, "WebSphere:type=JvmStats,*") host: <server1_hostname> userdir: $WLP_DIR/wlp/usr server: server1 host: <controller_hostname> userdir: $WLP_DIR/wlp/usr server: controller # --- collecting for <server1_hostname>:$WLP_DIR%2Fwlp%2Fusr:server1 routing_context: True MBean details for WebSphere:type=JvmStats 7 attributes UsedMemory [long] = 33044912 FreeMemory [long] = 13342288 Heap [long] = 46792704 UpTime [long] = 69644602 ProcessCPU [double] = 0.118396306716 GcCount [long] = 309 GcTime [long] = 649 0 operations # --- collecting for <controller_hostname>:$WLP_DIR%2Fwlp%2Fusr:controller routing_context: True MBean details for WebSphere:type=JvmStats 7 attributes UsedMemory [long] = 57614496 FreeMemory [long] = 13676384 Heap [long] = 72417280 UpTime [long] = 69657171 ProcessCPU [double] = 0.0867987941057 GcCount [long] = 432 GcTime [long] = 1025 0 operations
在本教程中,您学习了如何使用 Jython 脚本从服务器或者从集合体控制器及其全体成员那里收集性能数据。通过按照这些步骤操作,您可以了解强大的内省功能,从而找到您所需的 MBean 并了解如何启动它们。
非常感谢 Michael C. Thompson 对本系列教程的审阅以及他所做的贡献。
以下参考资料在阅读本教程时很有帮助: