使用Spring AOP快速定位线上项目性能问题

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/wangchengming1/article/details/98068040
前提

这篇文章以Spring AOP为例,介绍如何快速定位执行效率较低的方法,从而解决服务运行较慢的问题。如果不是很了解Spring AOP的小伙伴,可以先看一下我的这篇文章:Spring学习之AOP,然后再回来继续看这篇文章。

背景

最近线上项目总是收到客户发来的邮件,吐槽有一些动作要等好几十秒才能有反应,问我们是不是项目出什么问题了。看到邮件的第一反应就想到可能有一些方法执行的时间太长了,导致用户的等待时间过长。所以要找到是哪些方法执行时间较长,才可以知道怎么去解决和优化。

定位执行时间较长的方法
  • 我想到的方法是:使用切面来打印方法的执行时间。因为这种方法最简单,不用在每个方法开头的地方加开始时间,在每个方法结束的位置加结束时间和总用时时间。
  • 代码如下
    • 首先定义一个注解
      @Target({ElementType.METHOD})
      @Retention(RetentionPolicy.RUNTIME)
      public @interface TrackingTime {
      }
      
    • 然后写一个切面
      @Component
      @Aspect
      @Slf4j
      public class TrackingTimeAspectj {
      
          @Pointcut("@annotation(xxx.xxx.xxx.aop.annotation.TrackingTime)")
          public void trackingTimePointCut() {
          }
      
          @Around("trackingTimePointCut()")
          public Object trackingTimeAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
              long startTime = System.currentTimeMillis();
              String methodName = joinPoint.getSignature().toLongString();
              log.info( "Start execute method (" + methodName + ") at "+CalendarUtil.now().toString());
              Object result = joinPoint.proceed();
              log.info("Call method (" + methodName + ") used time:" + (System.currentTimeMillis() - startTime));
              return result;
          }
      }
      
    • 在可能会出现问题的方法上加上@TrackingTime这个注解,类似这样子
      	@TrackingTime
          public List<Class> save(){
          	// TODO
          }
      
    • 最后查看log,就可以很清晰的看到每个方法执行总用时,从而快速定位到问题所在。比如这个截图的效果,看到这个方法执行了接近20s,那么执行慢的方法找到了,接下来就要去考虑如何优化这个方法。
      在这里插入图片描述
解决方案

仔细看了一遍这个方法,发现问题有两个:

  • 在创建order的时候,数据量过大,没有采用异步的方法执行
  • 保存数据的时候,频繁的链接数据库

那么对应的解决方案就是:

  • 采用异步加载数据
  • 减少与数据库的链接次数,采用批量处理的方法

猜你喜欢

转载自blog.csdn.net/wangchengming1/article/details/98068040