摘要
经过大量的劳动,应用程序终于被部署到生产环境中并运行了。但是,已部署的应用程序还存在一些需要修复的问题。编写应用程序的开发人员和IT如何识别并解决已部署的应用程序中的问题呢?开发人员不希望自己开发的应用程序成为生产环境中的无法管理的实体。类似地,IT管理人员无疑也希望能够迅速找出已部署应用程序中出错的地方,以便尽快地解决问题,将停机时间降至最短。
解决这个两难问题的一种方法就是将可管理性内置到应用程序中。本教程主要关注用于在J2EE应用程序中设计管理特性的JMX (Java Management Extensions)。我将介绍JMX的基本知识,并展示如何使用JMX在BEA WebLogic Workshop 8.1环境中为一个简单的J2EE应用程序添加管理特性。我还将介绍JMX Metric Builder,一个可以帮助J2EE开发人员使用MBean来配置由HP OpenView BEA WebLogic SPI(Smart Plug-in)管理应用程序管理的可管理指标。HP OpenView所提供的端到端管理解决方案不仅预防了应用程序停机,还使业务线(line-of-business,LOB)管理人员可以知道应用程序的运行状态所产生的业务影响。
应用程序可管理性
可管理性是指对一个组件执行管理和监控操作并接收与此类操作相关的信息的能力。应用程序可管理性允许在生产管理中对应用程序进行管理和控制。

图1. 应用程序可用性影响着业务收益率
请看图1:过去,当与IT通信时,应用程序通常只简单地记录一个“数据库出现故障”的错误消息。其可管理性相当原始!而现在,应用程序需要为LOB提供高级可管理性,给出诸如“由于数据库出现故障而导致的损失是每小时一万美金”之类的消息。利用此类极有价值的信息,企业可以调整流程,以便获得最大的收益,同时将损失降至最少。可管理的应用程序所带来的好处并不局限于企业内部。信息未必与基础架构的健康状况相关,它也可能是出现业务事务问题的信号。
JMX基础
JMX是一个规范,它定义了如何通过一个公共接口来管理Java资源。该规范包括了Java编程语言中的架构、设计模式、API,以及用于应用程序和网络管理和监控的服务。
图2所示的JMX架构包含了以下4个层:
- 工具层(Instrumentation layer)
- 代理层(Agent layer)
- 分布式层(Distributed layer)
- 管理程序层(Manager layer)

图2. JMX架构
我将依次介绍每一层
工具层
工具层管理诸如应用程序、设备或服务之类的资源。可以使用称为Managed Bean (MBean)的Java对象来实现对管理资源的访问。管理资源是可以帮助确定应用程序状态的应用程序属性。其中包括系统级的信息(比如数据库出现故障)、与业务逻辑相关的信息(比如每小时损失一万美金),以及服务级的信息(比如可用性和响应时间)。
Mbean封装了一个资源,并通过一个JMX代理将其管理接口公开,以供远程管理和监控。有四种类型的MBean:标准型MBean、动态型MBean、开放型MBean、模型型MBean。
代理层
代理层定义了一个包含MBean服务器和代理服务的JMX代理。MBean服务器是注册MBean的JMX代理的主要组件。MBean必须向该服务器注册,否则管理框架便无法发现它们。MBean服务器还处理在已注册的MBean之间发送的管理消息。MBean服务器可运行在大多数支持Java编程语言的设备上。
代理服务表示一个包括一组用于处理MBean的服务的JMX代理。JMX直接控制资源,并使它们对远程管理代理可用。代理服务包括动态类加载、监控器、计时器和关系。
分布式层
分布式层拥有协议适配器和连接器。协议适配器和标准连接器允许从JMX代理的Java虚拟机外部的远程管理应用程序访问该代理。协议适配器通过一个特定的协议提供了一个关于MBean服务器中注册的所有MBean的视图。
连接器包括一个通过各种协议(例如:HTTP、HTTPS、IIOP)提供与代理的端到端通信的远程组件。J2SE平台包括用于运行在远程位置的应用程序的标准RMI连接器。因为使用不同协议的JMX连接器提供了相同的基于Java技术的接口,所以管理应用程序可以使用最适合于自己的网络环境的连接器,甚至在需要的时候透明地改变连接器。JMX代理也可以被那些不兼容JMX规范但却支持JMX代理的系统或应用程序使用。
管理程序层
管理程序层包括位于JMX代理的Java虚拟机外部的远程管理应用程序。该层的例子包括BEA WebLogic Server的Administration Console、JMX Metric Builder、HP OpenView SPI、HTML browser和JConsole。
关于JMX的更深入的介绍,请参见WebLogic Server产品文档。
案例分析
现在我将展示一个可在WebLogic Workshop 8.1中开发的基于J2EE的应用程序,Movie Kiosk。然后我们将使用管理特性通过针对某些目标属性创建JMX MBean来扩展示例程序。Movie Kiosk应用程序的前端被实现为驻留在WebLogic Server上的Web应用程序。其后端功能是通过一个Web服务实现的(见图3)。该Web服务将MBean公开为它的管理接口。

图3. WebLogic Workshop中的Movie Kiosk项目
Movie Kiosk应用程序提供了以下功能:
- 已注册用户的登录和新用户的注册;
- 下载一个电影以便预览或购买;
- 跟踪一些统计信息,包括购买下载次数以及有效和无效的登录次数
图4显示了Movie Kiosk应用程序的主页面,其中显示了来自一个特定类别的不同电影。从列表中选择一个电影之后,就可以单击Buy按钮购买它。

图4. Movie Kiosk主页面
对业务线的意义
从管理的角度来看,业务线管理人员将通过业务指标监控在线业务。他们需要看到访问Movie Kiosk Web站点并进行购买的客户的购买下载次数。为了满足这一需求,开发人员应该在现有的应用程序中实现JMX MBean,以便跟踪由客户启动的特定业务事务,从而随时产生“已完成的购买”次数。
后面您将看到,只需创建JMX MBean,就可支持许多可管理特性。
创建JMX MBean
下面该说说开发细节了。如果您只是想知道结果,那么可以跳过这一节。我将介绍如何向Movie Kiosk添加管理功能。这一步中我要开发的MBean属于标准型MBean,这是最简单的MBean类型。当您知道管理接口该是什么样的时候,就应该使用这种类型的MBean。
本节将介绍如何定义、实现、注册和调用该标准型MBean。将使用MoviePurchaseStats MBean类定义并实现MoviePurchaseStatsMBean接口。PurchaseDownloadsCount属性被公开为一个可能的指标。
对于标准型MBean,必须定义一个接口来公开可对该MBean调用的各种方法。这里定义了:(1)属性方法,即get和set方法;(2)操作,这里是可用来改变MBean的状态或特征的高级操作。在下面为MoviePurchaseStatsMBean定义的接口中,只有以下属性;
public interface MoviePurchaseStatsMBean {
public int getPurchaseDownloadsCount ();
//public
public double getTotalValueOfPurchases ();
public String getTotalValueOfPurchasesString ();
}
我还将定义另一个MBean接口,用于收集有关有效和无效登录次数的信息:
public interface AuthenticationStatsMBean {
public int getInvalidLoginCount ();
public int getValidLoginCount ();
public int getNewRegistrationCount ();
}
现在来看一个MBean的实现,MoviePurchaseStats。对于标准型MBean,必须实现刚才看过的接口。这里的要点是,该类的命名必须是接口名称去掉MBean后缀。这是MBean服务器对实现的要求。下面是代码:
public class MoviePurchaseStats implements
MoviePurchaseStatsMBean, java.io.Serializable {
public MoviePurchaseStats () {
}
/**
* Methods supporting the "PurchaseDownloadsCount" attribute.
*/
private int m_nPurchaseDownloadsCount = 0;
public int getPurchaseDownloadsCount () {
return m_nPurchaseDownloadsCount;
}
protected void resetPurchaseDownloadsCount () {
m_nPurchaseDownloadsCount = 0;
}
protected void incrementPurchaseDownloadsCount () {
m_nPurchaseDownloadsCount++;
}
}
可以看出,代码非常简单明了。注意,incrementPurchaseDownloadsCount()只将电影购买下载次数加1。随后它将用于装备应用程序。最后一个类AuthenticationStats也是一个标准型MBean,用于计算登录次数:
public class AuthenticationStats implements
AuthenticationStatsMBean, java.io.Serializable {
public AuthenticationStats () {
}
/**
* Methods supporting the "InvalidLoginCount" attribute.
*/
private int m_nInvalidLoginCount = 0;
public int getInvalidLoginCount () {
return m_nInvalidLoginCount;
}
protected void resetInvalidLoginCount () {
m_nInvalidLoginCount = 0;
}
protected void incrementInvalidLoginCount () {
m_nInvalidLoginCount++;
}
/**
* Methods supporting the "ValidLoginCount" attribute.
*/
private int m_nValidLoginCount = 0;
public int getValidLoginCount () {
return m_nValidLoginCount;
}
protected void resetValidLoginCount () {
m_nValidLoginCount = 0;
}
protected void incrementValidLoginCount () {
m_nValidLoginCount++;
}
}
部署MBean
定义了MBean之后,就需要将其部署到WebLogic Server上了。为此,在命名上下文中查找,获得一个到MBean服务器的引用。下面是例子:
public MovieKioskServices () {
/**
* Obtain a reference to the MBeanServer by looking it up in the
* naming context for the WebLogic Server. This will return to
* use the MBeanServer whose default domain is "weblogic." This
* is the MBeanServer we want to publish our MBeans into.
*/
InitialContext context = new InitialContext();
ms_mBeanServer = (MBeanServer)context.lookup(
weblogic.management.RemoteMBeanServer.JNDI_NAME);
}
接下来,向MBean服务器注册MBean。每个JMX Mbean都必须有一个对象名。对象名是JMX类ObjectName的实例,而且必须遵从由JMX规范定义的语法。这意味着它必须包含一个域以及一个关键属性列表。在下面的例子中,我定义了一个独有的域,myappdomain,以及一个Name=MoviePurchaseStatsMBean属性,我将其传递给ObjectName类的构造函数。最后,我将MBean发布给MBean服务器。
/**
* Create the "movie purchase statistics" MBean and publish it.
*/
ms_MoviePurchaseStats = new MoviePurchaseStats ();
ObjectName purchaseObjectName = new ObjectName (
"myappdomain:Name=MoviePurchaseStatsMBean" );
if ( ms_mBeanServer.isRegistered( purchaseObjectName ) ) {
ms_mBeanServer.unregisterMBean( purchaseObjectName );
}
ms_mBeanServer.registerMBean (ms_MoviePurchaseStats,
purchaseObjectName );
装备应用程序
定义了MBean并向WebLogic Server注册之后,我将通过调用MBean来装备应用程序。这是执行当单击图4中的Buy按钮时所触发的MBean管理的“行动”步骤。
/**
* @common:operation
*/
public String buyMovie ( String strUserID, String strMovieName )
{
String strURL = null;
strURL = (String)ms_htMovieURLs.get(strMovieName); //robot1.swf;
/**
* Update management information.
*/
ms_MoviePurchaseStats.incrementPurchaseDownloadsCount();
ms_MoviePurchaseStats.addToTotalValueOfPurchases( 115 );
return strURL;
}
现在,我准备在BEA WebLogic Workshop中编译该项目,该环境编译了所有的类。
使用HP OpenView进行WebLogic Platform管理
现在JMX MBean已经准备好进行管理了,我将介绍如何使用公开的MBean属性来创建管理指标,以及HP OpenView如何收集MBean数据来监控这些管理指标。首先我将带您快速概览HP OpenView管理解决方案,然后介绍新工具JMX Metric Builder。
HP OpenView管理解决方案产品组合可帮助您控制IT和电信资源。对于BEA WebLogic Platform管理,我使用用于BEA WebLogic Server 8.1的HP OpenView Operations (OVO)和Smart Plug-in (SPI)。
OVO监视、控制支持业务流程的IT基础架构,并报告其健康状况。OV SPI通过提供被管理的应用程序与HP OpenView之间的通信链路,从而使HP OVO能够显式地管理中间件和数据库产品。用于BEA的WebLogic Platform的SPI (WLSSPI)允许您使用HP OpenView利用平台中的MBean来管理和监控WebLogic Server实例。您还可以创建自己的定制MBean,或者创建一些用户定义指标(称为UDM)来管理和监控运行在该平台上的应用程序。HP OVO控制台为您提供了一个可以查看应用程序和应用服务器平台的单一视图,以便您可以在一个地方集中管理和监控应用程序和平台。
管理Movie Kiosk
我将介绍如何将OVO与WLSSPI结合使用来管理配备了JMX的示例应用程序。在管理环境中,HP OpenView WLSSPI执行大量的操作来收集每个指标的JMX数据,如图5所示:
- 有两种类型的OV模板。收集器模板指定了MBean属性值的收集时间间隔。指标模板通过为一种指标定义阈值条件来监控该指标的性能等级。
- 当收集器模板中的设置就绪之后,OVO Monitor Agent就启动了。它将与JMX SPI Agent交互,后者包含一个JMX Collector。
- JMX Collector访问一个User-defined Metrics(用户定义指标,UDM)文件,其中包含对通过JMX Metric Builder创建的JMX对象和属性的引用。这些JMX属性被映射为管理指标,这些指标就是我们的监控目标。
- JMX Collector与运行在WebLogic Server中的MBean服务器交互,并检索指定的MBean属性数据。
- JMX Collector执行所有的计算,并将所得的值提交回OVO Monitor Agent,代理将指标值与指标模板中所定义的阈值相比较。
- 根据比较结果,可能向OVO控制台发送一条警告消息,或者会以电子邮件或者其他形式通知负责监控该应用程序的人。

图5. BEA WebLogic Server的HP OV管理
在接下来的几节中,我将深入介绍如何定义UDM来管理Movie Kiosk应用程序中的一个JMX托管资源。首先我们将详细看一下UDM定义文件。在HP OpenView管理解决方案中,该文件是从WebLogic Platform访问JMX数据的关键。
构建JMX指标
UDM是一个XML配置文件,它定义了OVO应该收集的定制JMX MBean。在一个UDM文件中,可以定义多个指标,每个指标都可以是到一个MBean属性的引用,或者一个组合了其他指标的定制计算指标。该配置文件提供了公开给HP OpenView的指标名称与特定MBean属性名的映射。
您可以使用JMX Metric Builder来编辑UDM文件,这是一个基于图形化用户界面的工具。开发人员和IT操作人员使用JMX Metric Builder来选择用于监控和定义HP OpenView指标的JMX Mbean,报警,并根据这些MBean做出报告。
JMX Metric Builder是作为用于BEA WebLogic Server的HP OpenView Smart Plug-in的一个标准部件而提供的。考虑到应用程序开发人员与IT操作人员之间通信的重要性,惠普还提供了单机版的JMX Metric Builder。现在,如果开发团队要创建和部署WebLogic Server应用程序,并且已经安装了HP OpenView BEA WLS SPI 3.5,那么作为WebLogic Workshop 8.1开发环境的扩展,JMX Metric Builder就也可以使用了,这改进了IT与开发人员之间的协作。
接下来,我们通过已开发的MoviePurchaseStatsMBean及其PurchaseDownloadsCount属性来展示如何将MBean属性映射为一个ID为kioskapp1000的指标。然后HP OpenView将对该指标进行监控。
首先,从WebLogic Workshop菜单栏中,选择Instrument -> JMX Metric Builder(图6)。

图6.从WebLogic Workshop调用JMB
将会产生一个对话框,可以在其中指定独有的MBean域名。这里,我键入了来自前面的JMX装备例子的myappdomain。我推荐开发人员通过添加作为MBean Object Name一部分的域名,将MBean发布到每个应用程序的独有域,因为OpenView WebLogic Server SPI是使用Name属性来识别该MBean的。指定一个独有域可以帮助发现和确定哪些MBean是重要的;JMX Metric Builder只显示那些与特定域相关联的MBean。

图7. MBean域名
单击OK,这将激活JMX Metric Builder,如图8所示。

图8. JMX Metric Builder
MBean Explorer显示了从已配置的服从JMX的MBean服务器所收集的MBean数据。MBean数据包含MBean服务器以及在每个MBean服务器上注册的MBean。Movie Kiosk应用程序定义了两个MBean,包括MoviePurchaseStatsMBean。
MBean Explorer中选中的MBean的属性值出现在Properties视图中。在MBean Explorer视图中,选择一个MBean。展开该MBean,查看其属性(图9)。

图9. MBean属性
在菜单栏中,选择File -> New。这将在生成器的编辑器面板中打开一个包含示例指标的新UDM文件。
添加公开的指标
要向UDM文件添加一个简单指标,在MBean Explorer视图中,展开MoviePurchaseStatsMBean。选择PurchaseDownloadsCount属性,并在其上右击,从其上下文菜单中选择Create Exposed Metric。该指标就被添加到UDM文件了(图10)。

图10. 添加简单的公开指标
公开指标的ID是包含一个前缀(kioskapp)和ID号码(1000)的独有名称——前缀和号码都将被OpenView WebLogic Server SPI引用。因为我是将该指标作为公开的指标添加的,所以它可以被SPI收集器识别。
Alarm复选框指示当指标值超出阈值时用户是否会收到OpenView报警信息。Report意味着该指标值会显示在OpenView Reporter中。Graph元素表示该指标值会显示在OpenView Performance Manager中。Previous确保指标值会保存在一个历史文件中,以便可以分清当前值与先前值的区别。
ObjectName和Attribute列出了MBean的对象名和属性名。Type设置该指标的实例和数据类型。FromVersion和ToVersion指定该指标有效的WebLogic应用服务器的版本范围。
添加隐藏指标
隐藏指标只用于计算。HP OpenView不对它们进行监控。我将为AuthenticationStatsMBean的ValidLoginCount和InvalidLoginCount属性添加两个隐藏指标。
要向UDM文件添加一个隐藏指标,在MBean Explorer视图中,展开AuthenticationStatsMBean。选择ValidLoginCount属性,并在其上右击,从其上下文菜单中选择Create Hidden Metric。该指标就被添加到UDM文件了。遵从与InvalidLoginCount相同的步骤。
添加计算指标
可以将单个的简单指标组合成为一个有用的粗粒度计算指标。要向UDM文件添加一个计算指标,在MBean Explorer视图中右击,并从其上下文菜单中选择New Metric...。将会打开一个Create Metric对话框。选择Calculated和Exposed单选按钮(图11)。

图11. 创建指标
单击replace the formula,将打开Calculation Editor。使用该编辑器,我创建了一个给出Movie Kiosk Web服务的有效登录百分比的指标。计算指标将其他的指标组合在一起。如图12所示,该计算指标使用了ValidLoginCount和InvalidLoginCount指标。

图12. 创建计算指标
最后,我们来看一下UDM文件的XML格式(图13)。
指标ID是kioskapp1000和kioskapp1001。Kioskapp是将在OV WebLogic Server SPI收集器模板中使用的指标前缀。

图13. UDM文件
要保存UDM文件,可在菜单栏中选择File -> Save as。可以使用默认文件名保存,也可以使用一个新文件名。
HP OpenView Operations
既然定义了UDM文件,就可以使用HP OpenView Operations控制台来定义管理阈值报警并控制收集指标值的频度。
在本例中,因为我希望当电影购买次数超过5时会产生报警,所以我将阈值设为5。消息文本是将报警消息发送到OVO控制台。在监控策略中,我将安全性设为高等级的,并指定了当超出阈值时要执行的操作(图14)。

图14. 监控策略
在收集器策略中,我确定了希望OVO收集指标的频度。如图15所示,我配置收集器程序,使其每隔5分钟运行一次。此外,我定制了收集器程序,使其收集指标1000和1001的数据。我还列出了要收集的UDM前缀(kioskapp)。这些设置与上面图13中的UDM文件相匹配。

图15. 收集器策略
现在,该测试最终结果了。在浏览器中访问已部署的Movie Kiosk应用程序(见图4),单击Buy按钮六次以触发管理操作。
然后切换到OVO Message Browser,查看消息视图中的消息(图16),它说明已经超出了阈值。该信息对LOB管理人员来说非常重要,有助于帮助其确定业务状态。例如,LOB管理人员可以发现潜在的电影热销,并确定电影有存货。其他类型的通知(比如电子邮件)也可以通过HP OpenView获得,并发送给负责监控该应用程序的人。

图16. HP OVO Message Browser
下载
您可以下载本教程中所使用的示例应用程序的源代码:KioskApp.zip.
结束语
IT机构一直在寻找降低成本和提升操作效能的机会。很明显,部署和维护问题可能会成为重要因素。过去,开发人员通常将管理划入IT操作的范围,而在开发应用程序时将主要精力放在功能和性能上。针对可管理性进行设计和开发可带来明显的好处,可以确保IT获得快速分析操作和业务需求并采取相应措施的信息。特别是,它使业务管理人员可以发现应用程序的业务性能。
在Movie Kiosk应用程序中,我借助于JMX MBean来实现J2EE可管理性。我介绍了如何将HP OpenView Operations与WebLogic Server SPI结合使用来管理部署在WebLogic Platform的应用程序。我还演示了如何定制WLSSPI来使用JMX Metric Builder工具从应用程序收集业务指标。希望通过本文,能够使您对如何着手使用JMX来直接在Java应用程序中创建可管理性有一个更好的理解。 |