Code Ease Code Ease
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档

神秘的鱼仔

你会累是因为你在走上坡路
  • 个人博客网站 (opens new window)
  • 好用的工具网站 (opens new window)
  • Java核心基础
  • 框架的艺术
  • 分布式与微服务
  • 开发经验大全
  • 设计模式
  • 版本新特性
数据库系列
大数据+AI
  • xxl-job
运维与Linux
  • 基于SpringBoot和BootStrap的论坛网址
  • 基于VuePress的个人博客网站
  • 基于SpringBoot开发的小功能
  • 做一个自己的IDEA插件
程序人生
关于我
  • 分类
  • 标签
  • 归档
服务器
  • Java核心基础

  • 框架的艺术

  • 分布式与微服务

  • 开发经验大全

    • 如何用Java写一个规范的http接口?
    • 一个成熟的Java项目如何优雅地处理异常
    • 项目经理最近感觉系统慢了,想知道整个系统每个方法的执行时间
      • (一)前言
      • (二)思路
      • (三)使用AOP记录时间
        • 3.1 引入依赖
        • 3.2 配置切面
        • 3.3 测试一下
        • 3.4 自定义一个注解
      • (四)关于记录数据的问题
      • (五)结果
    • 财务说账单上少了一分钱,老板看到代码气疯了
    • 浅析五种最常用的Java加密算法,以后可以直接拿来用了
    • 你真的会用idea进行debug吗?idea实用debug教程
    • 还不知道项目中怎么写日志?slf4j+log4j帮你搞定!
    • 如何在工作中快速上手Git
    • 号称"最强API文档工具"的Swagger到底厉害在哪
    • 分享工作一年后收藏的超好用Idea插件,工作效率直接翻倍
    • 怎样才能写出规范的好代码?
    • 如何上传自己的jar包到maven中央仓库(2021最新版)
    • 使用Optional更优雅地处理非空判断
    • 查准考证网站卡了整整一个小时进不去,被抢票支配的恐惧又来了
    • 线上报了内存溢出异常,又不完全是内存溢出
  • 版本新特性

  • Java
  • 开发经验大全
CodeEase
2023-10-24
目录

项目经理最近感觉系统慢了,想知道整个系统每个方法的执行时间

作者:鱼仔
博客首页: codeease.top (opens new window)
公众号:Java鱼仔

# (一)前言

最近到年底了,上线三个月的系统也已经稳定了。不过项目经理最近感觉系统变慢了,想知道整个系统前端和后端所有方法的执行时间。是的你没有听错,是每个方法。这个需求一提出来就被整蒙了,给每个方法计算执行时间,这不是平白给系统压力吗?

# (二)思路

既然提了,先给思路吧。其实很简单,每个方法执行前记录一个时间戳,执行结束后记录一个时间戳,相减就是执行时间。但是去每个方法里改是不现实的,那么多代码,如果去侵入那工作量也太大了,而且如果有一天项目经理又不要这个功能了呢?

一听到这个需求,就应该想到AOP,用了那么久的Spring,IOC、AOP背的滚瓜烂熟,现在就是应用的时候了。

# (三)使用AOP记录时间

AOP的概念就不在这里提了,面向切面,无侵入开发,正适合这个需求。而且20行代码可以解决问题。

# 3.1 引入依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>
1
2
3
4

# 3.2 配置切面

首先配置一个切入点,我这里要让切面在TestController这个类中的所有方法上生效

@Slf4j
@Component
@Aspect
@Order(10)
public class LogAspect {

	//配置切入点,即执行的位置
    @Pointcut("execution(* com.javayz.codinguser.controller.TestController.*(..))")
    public void pointCut(){
    }

	//使用环绕通知,在方法的执行前后分别记录一个时间相减
    @Around("pointCut()")
    public Object doLog(ProceedingJoinPoint proceedingJoinPoint){
        long startTime = System.currentTimeMillis();
        Object object=null;
        try {
            object=proceedingJoinPoint.proceed();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }finally {
            long endTime = System.currentTimeMillis();
            log.info(proceedingJoinPoint.getSignature().toShortString()+"方法执行了:"+(endTime-startTime)+"ms");
        }
        return object;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

TestController方法是这样的:

@RestController
@RequestMapping("/testApi")
public class TestController {

    @GetMapping("/test1")
    public String testAop(){
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "testAop";
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 3.3 测试一下

直接调用/testApi/test1,效果出来了

# 3.4 自定义一个注解

现在已经可以满足项目经理的需求了,如果以后新的代码没有在切入点的范围内,就又不生效了,因此定义一个注解吧,要记录时直接写个注解

@Target(value = ElementType.METHOD)
@Retention(value = RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {
}
1
2
3
4
5

配置切入点的时候增加注解

@Pointcut("execution(* com.javayz.codinguser.controller.TestController.*(..)) || @annotation(com.javayz.codinguser.annotation.LogAnnotation)")
public void pointCut(){
}
1
2
3

好了,在需要执行的时候加上这个注解就OK了。

# (四)关于记录数据的问题

项目经理还希望可以随时查某个时间的方法执行时间,那就必须存下来这些数据了。

现在这个系统共有4万人使用,如果存入数据库,我在表里定义三个字段:时间、调用人员、调用时间,调用方法,一条数据大约在40字节大小。按四万个人的使用,一天最少也要产生4000万条数据,大约1.5G。数据量倒是没关系,对数据库写入的压力就更大了。

如果存在日志里也一样,日志会变得特别大,而且排查起来不方便。

# (五)结果

最终,在和项目经理一顿讲理之后,终于改变了他的想法,只记录执行时间超过200ms的方法,并且数据就记录下日志里,这个需求也算是通过沟通和小部分代码就解决了。好了,我们下期再见!

上次更新: 2025/02/18, 11:30:08
一个成熟的Java项目如何优雅地处理异常
财务说账单上少了一分钱,老板看到代码气疯了

← 一个成熟的Java项目如何优雅地处理异常 财务说账单上少了一分钱,老板看到代码气疯了→

最近更新
01
AI大模型部署指南
02-18
02
半个月了,DeepSeek为什么还是服务不可用
02-13
03
Python3.9及3.10安装文档
01-23
更多文章>
Theme by Vdoing | Copyright © 2023-2025 备案图标 浙公网安备33021202002405 | 浙ICP备2023040452号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式