在本系列的第 7 部分中。我们介绍了在 WebSphere Studio Application Developer Integration Edition V5.1.1 中为以下定制加工处理系统(Order to Manufacturing Processing System,OTMPS)的 KPI 创建事件:
- 平均定购吞吐量。要处理的定购总数/要花费的总时间
- 成功率。成功结束的程序实例的数量/程序实例的总数
- 无效定购的数量。验证失败的定购总数量
- 平均的解决问题时间。在很短的期间内,花费在纠正系统失败的平均时间
在本文中,我们将介绍如何利用由 CEI 提供的 Event Access 和 Event Distribution 服务来接收这些事件并创建业务流程监控应用程序。
为了由事件来创建 KPI,首先要创建对象模型来表示事件到 KPI 的映射。您可以使用该对象模型创建并获取 KPI。然后创建合适的 EJB 以获取事件并利用对象模型创建 KPI。在本部分,我们将介绍 OTMPS 的对象模型和获取事件的方法。
如图 1,新建的对象模型获取了所需的 KPI 规范的度量。该模型包括三层:事件、度量和集合。
- 事件层代表度量所依赖的事件。这些事件密封了相应的 CBE。
- 度量层代表重要的流程度量。流程度量利用事件层的事件计算度量。例如,ThroughPut 度量利用 OTMPS 启动、停止和定购数据事件来计算平均吞吐量。
- 集合层代表流程度量集合,并能够计算所需的 KPI。集合类是单例类,并利用事件服务器上所获得的事件由 EJB 进行填充,且由前端通过会话外观显示 KPI 来进行访问。
图 1. OTMPS 度量模型
表单 1 和表单 2 分别展示了 ThroughPut 和 ThroughPutCollection 类的代码。
表单 1. 吞吐量度量类
public class ThroughPut extends Metric {
private OTMPSStartEvent startEvent;
private OrdersDataEvent ordersEvent;
private OTMPSStopEvent stopEvent;
private int ordersProcessed;
private long processingTime;
private double throughPut;
public ThroughPut(OTMPSStartEvent _startEvent, OrdersDataEvent
_ordersEvent, OTMPSStopEvent _stopEvent) {
startEvent = _startEvent;
ordersEvent = _ordersEvent;
stopEvent = _stopEvent;
processingTime = stopEvent.getCreationTime()-
startEvent.getCreationTime();
if (stopEvent.isCompletionSuccessful()) {
ordersProcessed = ordersEvent.getNumberOfOrders();
}
throughPut = ordersProcessed/processingTime;
}
// getters
|
表单 2. ThroughPutCollection 类
public abstract class MetricCollection {
protected Vector metrics;
protected MetricCollection() {
metrics = new Vector();
}
public void addMetric(Metric metric){
metrics.add(metric);
}
}
public class ThroughPutCollection extends MetricCollection {
public static ThroughPutCollection eINSATNCE = new
ThroughPutCollection();
public double getAverageThroughPut() {
double totalNumberOfOrdersProcessed = 0;
double totalProcessingTime = 0;
for (int i=metrics.size(); i>0; i--) {
totalNumberOfOrdersProcessed =
totalNumberOfOrdersProcessed +
((ThroughPut)metrics.get(i-
1)).getOrdersProcessed();
totalProcessingTime = totalProcessingTime +
((ThroughPut)metrics.get(i-
1)).getProcessingTime();
}
return
(totalNumberOfOrdersProcessed==0?0:totalNumberOfOrdersProcessed/totalPr
ocessingTime);
}
}
|
为了要创建度量,您需要由 OTMPS 发出的事件。CEI 提供两个接收事件的接口:Event Access 接口和 Event Distribution 接口。Event Access 接口允许事件消费者同步地查询历史事件。Event Distribution 接口是 Java 消息传递服务(Java Messaging Service,JMS)接口,并允许事件消费者在事件发出后异步地接收事件。要了解更多关于开发事件消费者的信息,请参见参考资料。
我们决定利用 Event Access 接口获得历史事件并利用 Event Distribution 接口获取新事件。在本部分,我们将举例说明如何利用 XPath 查询历史事件以及如何定义事件组及如何通过 Event Access 接口来使用事件组。我们还将说明如何实现接收来自于 Event Distribution Interface 的事件的消息驱动的 bean(message- driven bean,MDB)。
事件可以通过 Event Access 接口来进行查询,该接口由 EventAccess 会话 bean 来实现。可以通过相应的主接口来创建 EventAccess bean 的实例,如清单 3 所示。
清单 3. 创建 EventAccess bean 的实例
// 利用主接口创建远程事件访问 bean
InitialContext context = new InitialContext();
Object eventAccessHomeObj =
context.lookup("ejb/com/ibm/events/access/EventAccess");
EventAccessHome eventAccessHome = (EventAccessHome)
PortableRemoteObject.narrow(eventAccessHomeObj,
EventAccessHome.class);
eventAccess = (EventAccess) eventAccessHome.create();
|
Event Access 接口支持以下查询事件的方式:
- 通过全局实例标识符。通过事件的关键字
globalInstanceId事件属性来得到事件。
CommonBaseEvent event = eventAccess.queryEventByGlobalInstanceId(eventId);
- 通过事件组。获取属于指定事件组的事件并(可选的)达到由事件选择器指定的标准。参见事件选择器和事件组以了解更多信息。
依照生成事件,用
ascendingOrder参数将事件按照升序或降序进行排列。maxEvent参数用于指定由事件查询返回的事件最大个数。CommonBaseEvent[] events = eventAccess.queryEventsByEventGroup(eventGroup, eventSelector, ascendingOrder, maxEvents);
- 通过关联类型。通过现有事件的 associationType 来获取关联的事件。一个事件可能有其他相关或关联的事件。关联类型属性定义了关系类型,比如:contains、cleared、causedBy、multiPart 或 correlated。
CommonBaseEvent[] events = eventAccess.queryEventsByAssocation(associationType, eventId);
如果事件分布(event distribution)服务启动了(默认)并且事件与事件组匹配,那么该事件就将分布到为事件组设定的队列中。默认地,CEI 以 JNDI 名称 “jms/cei/notification/AllEventsTopic” 来定义 “CommonEventInfrastructure_AllEventsTopic”,并将其关联到默认事件组 “All events”。
事件消费者可以实现消息驱动的 bean(MDB)并将其关联到适当的 JMS 目标以接收事件。如清单 4 所示,CEI 还提供了一个 MDB 用来将接收到的 JMS 消息转换成 CBE 实例的通告助手。
清单 4. 利用通告助手来将 JMS 消息转换成 CBE
// 由 JNDI 获得通告助手工厂
InitialContext context = new InitialContext();
Object notificationHelperFactoryObject =
context.lookup("com/ibm/events/NotificationHelperFactory");
NotificationHelperFactory nhFactory = (NotificationHelperFactory)
PortableRemoteObject.narrow(notificationHelperFactoryObject,
NotificationHelperFactory.class);
// 创建通告助手
NotificationHelper notificationHelper =
nhFactory.getNotificationHelper();
// 当前 CREATE_EVENT_NOTIFICATION_TYPE 是唯一的消息类型。
int msgType = notificationHelper.getNotificationType(msg);
if(msgType == NotificationHelper.CREATE_EVENT_NOTIFICATION_TYPE)
{
CommonBaseEvent event = notificationHelper.getCreatedEvent(msg);
if (event != null) {
// Process the event
.....
}
}
|
- 创建事件组:利用 WebSphere Administration Console 创建事件组,如果需要,将事件组与适当的 JMS 目标关联。
- 查询历史事件:书写会话 bean 或 servlet,并利用 Event Access 接口,通过事件组查询历史事件。
- 接收新事件:书写消息驱动 bean,并利用 Event Distribution 接口接收新的事件,将其与历史事件结合。
在 WebSphere Business Integration Server Foundation V5.1.1 中,可以利用管理控制台来创建事件组概要文件。在管理控制台中,选择 Resources > Common Event Infrastructure Provider > Event Group Profile List > Event groups list > Event Group Profiles > New。还可以利用 WebSphere Studio Application Developer Integration Edition V5.1.1 中的“集成测试环境” WebSphere 版本 5.1 的服务器来创建事件的概要文件,如 图 2 所示。但是在创建服务器过程中,确保选择了 Enable the Common Event Infrastructure,如图 3 所示。此操作将会自动在服务器上安装默认配置的 CEI。
图 2. 利用 WebSphere Administration Console 创建事件组
图 3. 在创建“集成测试环境”服务器时,启用 CEI
注意:在 WebSphere Studio Application Developer Integration Edition V5.1.1 中,创建 CEI “所有事件主题连接工厂”(CommonEventInfrastructure_AllEventsTopicCF)会将端口(Port)设置为 DIRECT。确保将其变更为 QUEUED,如图 4 所示,否则事件通告和事件创建将因此失败。
图 4. 为 CommonEventInfrastructure_AllEventsTopicCF 将端口设置为
QUEUED
WebSphere Business Integration Server Foundation V5.1.1 将事件组定义存储在 <WAS_INSTALL_DIR>/config/cells/<cell_name>/resource-cei.xml 文件中。如果是 WebSphere Studio Application Developer Integration Edition V5.1.1 的情况下,可以在 <WORKSPACE_DIR>/Servers/ <server_config_name>.wsc/cells 目录下找到该文件。
对于 OTMPS,我们创建了以下事件组:
-
ProcessStartEventGroup:
CommonBaseEvent[extensionName='WPC:ProcessinstanceEvent' 和 situation[@categoryName='StartSituation']] -
ProcessStopEventGroup:
CommonBaseEvent[extensionName='WPC:ProcessinstanceEvent' 和 situation[@categoryName='StopSituation']] -
OrdersDataEventGroup:
CommonBaseEvent[extendedDataElements[@name='WPCEventCode' 和 @type='string' and values='21090'] 及 extendedDataElements[@name='elementName' 和 @type='string' and values='orders'] -
InvalidOrdersEventGroup:
CommonBaseEvent[extendedDataElements[@name='WPCEventCode' 、 @type='string' 和 values='21090'] 及 extendedDataElements[@name='elementName' 、 @type='string' 和 values='invalidOrders']
您可以在应用程序启动过程中查询历史事件,以便在接收任何新事件之前历史事件就可用。出于该目的,创建 WebSphere 启动 bean 并在 start() 方法中查询历史事件。(要了解更多关于创建 WebSphere 启动 bean 的内容,请参见参考资料中所列出的 "WebSphere Business Integration Server Foundation V5.1 手册" 。)首先获得流程启动事件,然后利用它们查询相关的事件,并创建相应的度量。例如,为了对 OrderProcessor 流程的启动事件进行查询,使用 StartEventGroup 并利用事件选择器对其加以更严格的限定以便只获取 OrderProcess 启动事件。然后,利用这些事件,通过使用相应的事件组并将事件组在流程环境中加以限定,来得到从流程启动事件中获得的完成、定购数据和无效的定购数据事件。根据 OTMPS 度量模型(参见 图 1),利用合适的事件创建 ThroughPut、Outcome 和 NumberOfInvalidOrders 度量,并将它们加入到相应的单例集合类中。清单 5 显示了我们使用的不同事件组和事件选择器。清单 6 显示出 startup() 方法的完整代码。
清单 5. OTMPS 的事件选择器
public class EventSelectors {
static String START_EVENT_GROUP = "ProcessStartEventGroup";
static String STOP_EVENT_GROUP = "ProcessStopEventGroup";
static String ORDERS_DATA_EVENT_GROUP = "OrdersDataEventGroup";
static String INVALID_ORDERS_DATA_EVENT_GROUP =
"InvalidOrdersDataEventGroup";
static String MILESTONEMANAGER_EVENT_SELECTOR =
"CommonBaseEvent[extendedDataElements[@name = 'processTemplateName' and
@type='string' and values = 'OrderProcessSystem']]";
static String EXCEPTIONHANDLER_EVENT_SELECTOR =
"CommonBaseEvent[extendedDataElements[@name = 'processTemplateName' and
@type='string' and values = 'ExceptionHandler']]";
static MessageFormat contextEventSelector = new MessageFormat
("CommonBaseEvent[contextDataElements[@name=\"ECSCurrentID\" and
@type=\"ECSID\" and @contextValue=\"{0}\"]]");
static MessageFormat validationSubprocessEventSelector = new
MessageFormat ("CommonBaseEvent[extendedDataElements[@name =
\"processTemplateName\" and @type=\"string\" and values =
\"ReleaseMileStone\"] and contextDataElements[@name=\"ECSParentID\" and
@type=\"ECSID\" and @contextValue=\"{0}\"]]");
}
|
为了接收新事件,将 StopEventGroup 与 JMS 目标相关联并书写一个消息驱动 bean 来接收新的停止事件。选择接收停止事件是因为我们只想在相应流程成功完成且没有取消或终结的情况下计算性能度量。而且,通过接收停止事件,我们能够避免在内存中保留事件或等待相关的事件。 清单 7 显示了我们如何处理新的停止事件。我们利用停止事件获得相应的启动事件并在需要的情况下,获得相关事件。
清单 7. 接收新事件
if (cbe != null) {
// 从启动事件中获得环境 id
String contextId = Event.getContextId(cbe);
//完成环境事件选择器
Object [] args = {contextId};
String contextEventSelector =
EventSelectors.contextEventSelector.format(args);
//获得相应的启动事件
CommonBaseEvent [] startCbes =
eAccessEjb.queryEventsByEventGroup(EventSelectors.START_EVENT_GROUP,
contextEventSelector, true);
Event event = EventFactory.createEvent(startCbes[0]);
if (event instanceof OTMPSStartEvent) {
OTMPSStartEvent otmpsStartEvent = (OTMPSStartEvent)event;
OTMPSStopEvent otmpsStopEvent = new OTMPSStopEvent(cbe);
//获得相关事件并创建相应的度量(与先前显示的 StartUp bean 的部分相同)
} else if (event instanceof ExceptionHandlerStartEvent) {
ExceptionHandlerStartEvent ehStartEvent =
(ExceptionHandlerStartEvent)event;
ExceptionHandlerStopEvent ehStopEvent = new
ExceptionHandlerStopEvent(cbe);
if (ehStopEvent.isCompletionSuccessful()) {
ProblemResolutionTime problemResolutionTime = new
ProblemResolutionTime(ehStartEvent, ehStopEvent);
ProblemResolutionTimeCollection.eINSTANCE.addMetric(problemResolu
tionTime);
}
}
}
|
为了露出集合类,您可以创建会话外观并通过 servlet 对其进行访问,这样能够将结果传到 JSP 上。图 5 显示了 KPI 监控的交互图。当调用 OTMPSMetrics servlet 时,该 servlet 找到 MetricsFacade 会话 bean 并对每个 KPI 调用关于该 bean 的 get<KPI>() 方法(例如,getAverageThroughput)。MetricsFacade 随后便调用相应的单例集合类来获得 KPI。在取得所有 KPI 之后,OTMPSMetrics servlet 将信息传送给能够将信息显示在浏览器中的 DisplayOTMPSMetrics JSP。
图 5. 显示 KPI
您还可以利用 WebPage portlet 将 KPI 集成到 WebSphere Portal Server 上,这样可以配置成调用 OTMPSMetric servlet。图 6 展示了 portal 视图中的 OTMPS KPI。
图 6. Portal View
在本文中,我们介绍了如何利用 CEI 创建定制的 Business Process Monitoring 应用程序。并举例说明了如何创建事件到 KPI 的对象模型映射及说明了如何利用这样的模型由事件创建 KPI。我们还介绍了如何利用 Event Access 和 Event Distribution 接口一起有效地接收事件,如何关联事件以创建 KPI,及如何在 portal 中对它们进行显示。
| 描述 | 名字 | 大小 | 下载方法 |
|---|---|---|---|
| Sample EAR file for BPM app | ws-odbp8code.zip | 309 KB | HTTP |
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文。
- 阅读随需应变业务流程的生命周期的所有部分,并且随时注意我们新的文章。
- 以下的信息中心和红皮书提供了关于能够了解更多关于公共基础事件模型的知识和使用公共事件基础架构方面的极好参考资料:
- WebSphere Business Integration Server Foundation 信息中心 —— 书写事件选择器
- WebSphere Business Integration Server Foundation 信息中心 —— 开发事件消费者
- “WebSphere Business Integration Server Foundation V5.1 手册”
-
从 DB2®、Lotus®、Rational®、Tivoli® 和 WebSphere® 得到应用程序开发工具和中间件产品。您可以免费下载该产品的评估版本,或者选择 developerWorks 的免费 Software Evaluation Kit 中的 Linux® 或 Windows® 版本。
- 访问 Developer Bookstore 以获取全面的技术书籍列表,包括数以百计的 Web 服务主题书籍。
- 通过参加
developerWorks blog 加入到 developerWorks 社区。
- IBM developerWorks 团队在全世界拥有成百的 技术简报,您可以免费参与。
- 要获得更多信息吗?DeveloperWorks SOA 及 Web 服务专区有成百的资料文章及关于开发 Web 服务应用程序的初级、中级和高级教程。