Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4584241
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Java

2016-09-28 17:53:47

原文地址:https://my.oschina.net/jack230230/blog/65987

如果你正在使用Spring()管理/访问资源(Dao/Service),那么你可能也需要添加一些基础的性能监控。在Spring AOP的帮助下这将变成一个简单的任务,不需要任何现有代码的变化,只是一些简单的配置。

第一步,你首先的将spring-aop、aspectj和cglib库导入,如果你使用maven管理你的项目依赖的话,很简单加上如下依赖关系就可以了。

<dependency> <groupId>org.aspectjgroupId> <artifactId>aspectjweaverartifactId> <version>1.5.4version> dependency> <dependency> <groupId>cglibgroupId> <artifactId>cglib-nodepartifactId> <version>2.2version> dependency> <dependency> <groupId>org.springframeworkgroupId> <artifactId>spring-aopartifactId> <version>2.5.6version> dependency>



接下来,指明你需要监视的内容,并把AOP配好。通常,仅仅需要在现有的SpringXML配置文件中增加一个横切点。这个配置将会将位于包"com.mycompany.services"下的所有方法的响应时间记录下来。注:这些类必须使用Spring context初始化,否则AOP将不会被执行。

<bean id="performanceMonitor" class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor" /> <aop:config> <aop:pointcut id="allServiceMethods" expression="execution(* com.mycompany.services.*.*(..))"/> <aop:advisor pointcut-ref="allServiceMethods" advice-ref="performanceMonitor" order="2"/> aop:config>



接下来,需要配置好日志系统,例如log4j。

<logger name="org.springframework.aop.interceptor.PerformanceMonitorInterceptor" additivity="false"> <level value="TRACE"/> <appender-ref ref="STDOUT"/> logger>



ok了,现在我们运行一下程序你会发现下面的日志输出:

TRACE PerformanceMonitorInterceptor  - StopWatch 'PerfTestService.processRequest': running time (millis) = 1322 TRACE PerformanceMonitorInterceptor  - StopWatch 'PerfTestService.processRequest': running time (millis) = 98 TRACE PerformanceMonitorInterceptor  - StopWatch 'PerfTestService.processRequest': running time (millis) = 1764



这些是大量的一些原始数据,但不幸的是这些东西对我们几乎没用,每一个方法调用都会有记录,而且缺乏一些其他信息。所以,除非你打算写一些日志分析程序、或者使用第三方软件,否则的话,我想你应该在日志被记录前做出一些处理。

一个简单的办法就是在这之间写一个简单的拦截器类来替代Spring给我们提供的默认的类(PerformanceMonitorInterceptor)。下面的一个例子,这个例子提供了一些有用的信息(最后一个、平均、最大的响应时间),另外当一个方法的响应时间超出指定的时间后给出警告。

默认的,每当十个方法调用的时候,做一次记录,在任何方法响应时间超过1000ms的时候给出警告。

public class PerfInterceptor implements MethodInterceptor {

     Logger logger = LoggerFactory.getLogger(PerfInterceptor.class.getName()); private static ConcurrentHashMap methodStats = new ConcurrentHashMap(); private static long statLogFrequency = 10; private static long methodWarningThreshold = 1000; public Object invoke(MethodInvocation method) throws Throwable { long start = System.currentTimeMillis(); try { return method.proceed();
        } finally {
            updateStats(method.getMethod().getName(),(System.currentTimeMillis() - start));
        }
    } private void updateStats(String methodName, long elapsedTime) {
        MethodStats stats = methodStats.get(methodName); if(stats == null) {
            stats = new MethodStats(methodName);
            methodStats.put(methodName,stats);
        }
        stats.count++;
        stats.totalTime += elapsedTime; if(elapsedTime > stats.maxTime) {
            stats.maxTime = elapsedTime;
        } if(elapsedTime > methodWarningThreshold) {
            logger.warn("method warning: " + methodName + "(), cnt = " + stats.count + ", lastTime = " + elapsedTime + ", maxTime = " + stats.maxTime);
        } if(stats.count % statLogFrequency == 0) { long avgTime = stats.totalTime / stats.count; long runningAvg = (stats.totalTime-stats.lastTotalTime) / statLogFrequency;
            logger.debug("method: " + methodName + "(), cnt = " + stats.count + ", lastTime = " + elapsedTime + ", avgTime = " + avgTime + ", runningAvg = " + runningAvg + ", maxTime = " + stats.maxTime); //reset the last total time stats.lastTotalTime = stats.totalTime;   
        }
    } class MethodStats { public String methodName; public long count; public long totalTime; public long lastTotalTime; public long maxTime; public MethodStats(String methodName) { this.methodName = methodName;
        }
    } 
}



现在,你只需要将你的Spring配置文件中做相关修改,将这个类应用进去,再运行程序,你将会看到如下的统计信息。

WARN PerfInterceptor - method warning: processRequest(), cnt = 10, lastTime = 1072, maxTime = 1937 TRACE PerfInterceptor - method: processRequest(), cnt = 10, lastTime = 1072, avgTime = 1243, runningAvg = 1243, maxTime = 1937 WARN  PerfInterceptor - method warning: processRequest(), cnt = 20, lastTime = 1466, maxTime = 1937 TRACE PerfInterceptor - method: processRequest(), cnt = 20, lastTime = 1466, avgTime = 1067, runningAvg = 892, maxTime = 1937



正如你看到的一样,这些统计数据可以在不修改任何现有的Java代码的情况下,提供有关class/method性能的有价值的反馈,而根据这个日志,你可以很轻松的找出程序中的瓶颈。

阅读(892) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~