From:http://www.theserverside.com/tt/knowledgecenter/knowledgecenter.tss?l=AOPforAPM
介绍:
应用开发人员使用一些传统的技术去监控性能管理。使用像PotimizeIt,JProbe 等通用的调试工具。另一个传统的方法是在代码的特殊地方插入时间和有用的信息。商业的性能管理工具同样使用不同的技术,例如 在类装载时的字节码探测,或者使用应用服务器的拦截器去修饰类。在此文中,我们介绍 一种 使用 Aspect Oriented Programming (AOP)的灵活多变的机制来处理应用程序性能管理。
注意:我们使用AspectJ[1] AOP库去阐述这种方法,此技术可适用于任意的AOP程序。
方法:
在插图1中,使用AOP技术“编织”的性能监视代码自动插入到已存在的应用程序中。为了更容易些,我们把性能监控逻辑(例如:计时器,统计计算等)划分成简单的库。传统方法是手动编码将程序库放到应用程序中,这种方法单调乏味并且易错。另一个好方法就是使用AOP特性,在应用程序中声明性能监视库需要创建的不同点,AOP工具 允许修改字节码并自动插入到这些调用中。
Figure 1: High-level Architecture
文章的下列部分假设读者基本熟悉
AOP概念[2,3],例如 pointcuts 和 advice。
实现:
我先从MonitoringFacade 类开始,它能计算一个API的执行时间。
public class MonitoringFacade {
public static long begin(Class clazz,
String method, String layer) { /* .. */ }
public static end(long startTime,
Class clazz, String method, String layer) { /* .. */ }
}
我们需要 在应用程序执行有意义地方的前或者后调用MonitoringFacade的一对begin/end方法。MonitoringFacade 类是一个普通的Java类,它来计算时间和使用统计,像min,max,average,first和last执行时间,这些是创建调用树(call trees)所需要的,把这些测量数据与那些收集上来的系统中的其他部分联系起来。我们写一个 abstract aspect ,它来调用MonitoringFacade。
public abstract aspect InfraREDBaseAspect {
/**
* The condition based on which monitoring is performed.
*/
public abstract pointcut operationToBeMonitored();
/**
* Gets the layer (Web, Hibernate, JDBC etc.) of the operation
*/
public abstract String getLayerName();
/**
* Calls the agent fa�ade before and after the execution of the
* monitored operation
*/
Object around() : operationToBeMonitored () {
final Class clazz =
thisJoinPointStaticPart.getSignature().getDeclaringType();
final String method =
thisJoinPointStaticPart.getSignature().getName();
final String layer = getLayerName();
long startTime = MonitoringFacade.begin(clazz, method, layer);
try {
return proceed();
} finally {
MonitoringFacade.end(startTime, clazz, method, layer);
}
}
}
抽象aspect 的具体实现 为被监控的特殊操作提供了切入点,例如session bean调用,Struts 执行,entity bean调用,Hibernate 查询等。他们同样提供一个layer name(例如:“Struts”,“Hibernate”等等),它关系到被收集的统计数据。这让我们提供感兴趣的统计,例如某层执行花费的全部时间,这些有利于性能和伸缩性分析。
我们已经编写一个具体的aspect,我们需要将它们“编织”到应用程序类中。“编织”是一个修改应用程序类字节码并插入Facade调用的过程。AspectJ 提供工具去做此事。
下面是一个具体的HibernateAspect类,它在"Hibernate Query" 范围内,定位和记录所有Hibernate的查询时间。
public aspect HibernateAspect {
public pointcut hib3Query :
execution(public java.util.List org.hibernate.Query+.list());
public pointcut hib3Find :
execution(public * org.hibernate.Session+.find());
public pointcut operationToBeMonitored() : hib3Query || hib3Find;
/**
* Gets the layer name of the operation
*/
public String getLayerName() {
return "Hibernate Query";
}
}
同样的,你能在普通的地方写不同的appect去捕获信息,例如:struts 执行时,JDBC 语句执行等等。如果需要的话,可以暴露pointcut定义,让用户很容易定制期望被监视的部分应用程序。
优点:
与其他方法相比,考虑更多高级的定制和更强的灵活性可以使用AOP工具的强大功能。下面列举一些优点:
·选择性的监控部分的应用程序而不是使用包名和API名去限制。pointcut定义语言有杠杆作用的功能,例如:监控APIs仅仅在当前执行上下文(使用AspectJ特性,像cflow),基于参数和它们的类型监视APIs,等等。
·在一个高层粒度去捕获统计的功能。举例:很容易收集在servlet层,Struts层,持久层,JDBC层等等的执行时间。AOP很容易通过声明pointcut 定义语言来定义这些层。
·灵活捕获更详细的统计信息。用户使用工具提供的特性,但使用这些工具不能完全展示AOP的功能。一些新功能的统计用它几乎不可能做到。例如:常用API的频率分布图,第一次和最后一次的执行时间,平均时间需要除去第一次执行的平均时间(除去第一次非常有用,因为一些API在第一次执行时做很多事情,比如读很多的数据并缓冲数据,如果包括了第一次执行时间,那么平均频率就不能显示增量请求所执行时间的真实数据)。InfraRED 提供了这些统计,但不是所有。即使这些特性在核心产品中不可用,AOP工具为用户提供了强大的自定义功能。
·生成调用树(call trees)的功能,调用树链接着不同的执行API的功能,使用像cflow[5] 创建的AspectJ程序,在程序可以轻易的实现此功能。
总结:
在这里我们介绍了一个在应用程序中收集性能统计数据的灵活方法,略述了这种方法与传统技术相比的几个优点。这篇文章来自于我在InfraRED (http://infrared.sf.net/)中的工作经验,一个基于AOP的开源的性能监控工具。
参考:
1.AspectJ homepage: http://www.eclipse.org/aspectj/
2.Introduction to AspectJ: http://www.eclipse.org/aspectj/doc/released/progguide/starting-aspectj.html
3.AOP without the buzzwords: http://jroller.com/page/colyer?entry=the_ted_neward_challenge_aop
4.InfraRED homepage: http://infrared.sf.net/
5.On using AOP for Application Performance Management: http://aosd.net/2006/archive/AOSD06-IndustryTrackProceedings.pdf
作者:
Srinivas Narayanan 是Tavant Technologies 公司的总架构师,提供软件企业解决方案。在Tavant,他监管一些大公司的J2EE项目,并创建一套基于java程序开发的可复用的平台。他是InfraRED项目的创始人。在Tavant之前,他工作在IBM Almaden 研究中心,在关系对象数据库系统领域。他在一些主要的研讨会上演讲了数篇关于企业级应用,SOA,系统集成和数据库的论文。他在美国麦迪逊的威斯康星大学获得了计算机科学硕士学位,在印度 Chennai IIT 获得计算机科学学士。
Binil Thomas 在Tavant Technologies是副架构师。他也是InfraRED项目的参与者。他在印度喀拉拉大学获得计算机科学学士。
感谢:Srinivas和Binil感谢他们的同事 Kamal Govindraj 提供的帮助。
声明:以上翻译是我在业余时间进行,因为英语水平有限,难免有些bug,多谢各位指教。
一个驻扎在天津的普通程序员,当个PM,TL,CODER 就是没有当过CEO。
My idiom:Where there is a will,there is a way!
注:加班写作,转载请著名出处!!