记一次用arthas成功排查性能问题

测试说我写的1个接口后TPS不达标,只有200多。 而一直性能不佳的下单接口竟然都有300多,那显然是我接口出问题了。

后用arthas排查后定位到耗时代码,比较简单,这里做个记录。

本地安装arthas

就完全参考的文档安装部署https://arthas.aliyun.com/doc/quick-start.html,文档写的很好,也不需要去搜别人的博客来学习使用。 支持本地windows安装的,真是很棒。

安装好后cmd黑窗口java -jar math-game.jar启动即可,然后输入1个数字选择具体某个jvm进程。

定位耗时代码

主要用到trace这个命令。 一步步trace到耗时的方法,定位到是这行:

ValidUtils.validateDTO(driverQRCodeDTO);

ValidUtils是我写的1个工具类,用来手动校验Validation,没想到就这块拉胯了。

代码如下:


import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

public static <T> void validateDTO( T dtoClass)  {
    // 取得一个Validator实例
    Validator validator = Validation.buildDefaultValidatorFactory().getValidator();


    // 调用Validator#validate方法对这个bean进行校验
    // 所有的
    // ConstraintViolation的泛型类型要设定为被校验bean的类型
    Set<ConstraintViolation<T>> errors = validator.validate(dtoClass);

    // 这里遍历errors这个set,打印出各个错误的信息
    errors.forEach(error -> {
        //TODO
    });

    if (errors.size() > 0) {
        // 可以取出所有的校验失败信息,拼接起来之后返回给调用方
        final String errMessages = errors.stream()
                .map(ConstraintViolation::getMessage)
                .collect(Collectors.joining(", "));

        throw new BusinessException(BusinessCode.PARAM_ERROR.getCode(), BusinessCode.PARAM_ERROR.getMsg());
    }
}

继续用trace命令:

trace com.xxx.xxx.enterprise.utils.ValidUtils validateDTO '#cost > 50' -n 100

结果如下。 果然如同我的猜想,是获取validator这个方法有性能问题。

image.png image.png

压测OK

注释掉这行代码后压测,线程组如下:

image.png

结果ok(开发环境上压着玩的,服务器性能一般,不过1k够了):

image.png

得出结论:

  • 能自己本地用jmeter压测不要自己写多线程模拟并发,不准!
  • 压本地环境TPS比压开发环境低,原因未知,arthas看了耗时在数据库。
  • 如开头所猜想,既然其他接口好的,事实证明也确实果然是这个接口的问题,而不是开发环境的网关服务或磁盘哪里耗时了。
  • 就算开发环境的服务器性能很差,数据库插入的压测都有2000,说明这次压测不达标不是数据库压力。

猜你喜欢

转载自juejin.im/post/7120537434391052318