分析Java Spring应用程序

问题描述 投票:15回答:8

我有一个Spring应用程序,我认为它有一些瓶颈,所以我想用一个分析器来运行它来测量哪些函数花了多少时间。有关我应该如何做的任何建议?

我正在运行STS,该项目是一个maven项目,我正在运行Spring 3.0.1

java spring profiling
8个回答
17
投票

我用Spring AOP完成了这个。

有时我需要一个关于在我的项目中执行某些方法需要多长时间的信息(例子中的Controller方法)。

在servlet xml中我放了

<aop:aspectj-autoproxy/>

另外,我需要为方面创建类:

@Component
@Aspect
public class SystemArchitecture {

    @Pointcut("execution(* org.mywebapp.controller..*.*(..))")
    public void businessController() {
    }
}

和探查器方面:

@Component
@Aspect
public class TimeExecutionProfiler {

    private static final Logger logger = LoggerFactory.getLogger(TimeExecutionProfiler.class);

    @Around("org.mywebapp.util.aspects.SystemArchitecture.businessController()")
    public Object profile(ProceedingJoinPoint pjp) throws Throwable {
        long start = System.currentTimeMillis();
        logger.info("ServicesProfiler.profile(): Going to call the method: {}", pjp.getSignature().getName());
        Object output = pjp.proceed();
        logger.info("ServicesProfiler.profile(): Method execution completed.");
        long elapsedTime = System.currentTimeMillis() - start;
        logger.info("ServicesProfiler.profile(): Method execution time: " + elapsedTime + " milliseconds.");

        return output;
    }

    @After("org.mywebapp.util.aspects.SystemArchitecture.businessController()")
    public void profileMemory() {
        logger.info("JVM memory in use = {}", (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
    }
}

就这样。当我从webapp请求页面时,有关方法执行时间和JVM内存使用情况的信息打印在我的webapp日志文件中。


4
投票

我推荐VisualVM进行一般应用程序分析。它在JDK版本1.6_10中可用,并且比Eclipse TPTP快得多且可用。

(如果您的Spring应用程序在应用程序服务器(例如Tomcat)中运行,您可以尝试将其部署到tc Server开发人员版本(可在STS downloads中获得)。它具有有趣的监视功能。似乎不再维护tc Server开发人员版本。)

更新2019.02.22。:更新了VisualVM URL(感谢@Jeff)和tc服务器信息。我个人目前使用Glowroot来监视在应用程序服务器中运行的Spring应用程序。


2
投票

您可以使用开源Java分析器,例如Profiler4J:

http://profiler4j.sourceforge.net/

或者Netbeans带有一个内置的分析器,Eclipse也有分析功能,但我发现Profiler4J更容易使用,因为它有一个很好的图表显示你最耗时的方法。

这在STS(eclipse)中运行良好,只需按照网站上的说明操作即可。


2
投票

我们开发了一个基于JMX和Spring AOP的@Profiled注释,它可以进行生产监控(主动调用,调用计数,调用期​​间花费的时间,异常计数等)。度量标准通过JMX公开,可以通过Visual VM / JConsole和监控系统收集;我们开发了Hyperic HQ插件。

这个@profiled注释与许多其他JMX附加组件一起打包,以便于监视常见组件(dbcp,util.concurrent,cxf,jms等),并在http://code.google.com/p/xebia-france/wiki/XebiaManagementExtras的商业友好Apache软件许可下提出。

希望这可以帮助,

Cyrille(Xebia)


1
投票

我喜欢JRat,虽然像profiler4j似乎没有积极开发。无论如何,它使用起来很简单。


0
投票

这是一个general discussion与推荐的工具和技术。

基本上,如果您想要了解如何更快地创建应用程序,那么您应该首先考虑功能需要多长时间。这是一种自上而下的方法。

有一种自下而上的方法,当你想到它同样自然。这不是要问时间,而是要问它主要是做什么,以及它为什么这样做。


0
投票

Yuri的答案在顶部(选定的答案)的一点修改版本,自动计算持续时间的总和并安排他们desc。总计仅在最后打印。可以为你节省10分钟。

    @Component
    @Aspect
    public class SystemArchitecture
    {

         @Pointcut("execution(* erp..*.*(..))")
         public void businessController()
         {
         }

         @Pointcut("execution(* TestMain..*.*(..))")
         public void theEnd()
         {
         }
    }



    @Component
    @Aspect
    public class TimeExecutionProfiler
    {

        static Hashtable<String, Long>  ht  = new Hashtable<String, Long>();

        @Around("profiler.SystemArchitecture.businessController()")
        public Object profile(ProceedingJoinPoint pjp) throws Throwable
        {
            long start = System.nanoTime();
            Object output = pjp.proceed();
            long elapsedTime = System.nanoTime() - start;
            String methodName = pjp.getSignature().toString();
            if (ht.get(methodName) == null)
            {
                ht.put(methodName, elapsedTime);
            }
            else
            {
                ht.put(methodName, ht.get(methodName) + elapsedTime);
            }
            // System.out.println(methodName + " : " + elapsedTime + " milliseconds.");

            return output;
        }

        @After("profiler.SystemArchitecture.theEnd()")
        public void profileMemory()
        {
            List<Object> keys = Arrays.asList(ht.keySet().toArray());
            java.util.Collections.sort(keys, new Comparator<Object>()
            {

                @Override
                public int compare(Object arg0, Object arg1)
                {
                    return ht.get(arg1).compareTo(ht.get(arg0));
                }
            });

            System.out.println("totals Used:");
            for (Object name : keys)
            {
                System.out.println("--" + name + " : " + (ht.get(name) / 1000000));
            }
            System.out.println("JVM memory in use = " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
        }
    }

0
投票

您始终可以使用与Java捆绑在一起的Java Mission Controls Flight Recorder来分析代码执行情况

© www.soinside.com 2019 - 2024. All rights reserved.