开发实战-优雅统计耗时情况

1,610 阅读2分钟

这是我参与11月更文挑战的第6天,活动详情查看:2021最后一次更文挑战

前言

临近双十一,为了保证服务稳定运行,经常去看服务监控,发现有些接口耗时很长。一次请求会占一个线程,请求耗时大的话,就会导致线程被占用的时间长,而运行中的线程只有那么多,那么其他请求进来就无法拿到线程去执行,阻塞住了。所以慢接口如果不及时去处理,就很容易导致整个服务卡死,如果这个服务是个基础服务,就会导致整个业务链上的所有服务出问题。那我们该如何去排查,去定位是啥导致接口响应慢的呢?

通常我们在接口每步的耗时情况,一般都会这样去做。在执行前先记录开始的时间

long start = System.currentTimeMillis();

然后结束时在计算出耗时,打印日志。

System.currentTimeMillis() - start

如果我们要记录每一步的耗时,就要重复写上面的代码,而且也没有一个整体的概况。接下来介绍一个开源工具hutool里的一个小功能stopwatch,来解决这一痛点。

Hutool

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool中的工具方法来自每个用户的精雕细琢,它涵盖了Java开发底层代码中的方方面面,它既是大型项目开发中解决小问题的利器,也是小型项目中的效率担当;
Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。

StopWatch

秒表封装
此工具用于存储一组任务的耗时时间,并一次性打印对比。

StopWatch stopWatch = new StopWatch("任务名称");

// 任务1,模拟耗时3s
stopWatch.start("任务一");
TimeUnit.SECONDS.sleep(3);
stopWatch.stop();

// 任务2,模拟耗时2s
stopWatch.start("任务二");
TimeUnit.SECONDS.sleep(2);
stopWatch.stop();

// 打印出耗时
Console.log(stopWatch.prettyPrint());

这样我们打印出来的是

StopWatch '任务名称': running time = 5007730919 ns
---------------------------------------------
ns         %     Task name
---------------------------------------------
3002986329  060%  任务一
2004744590  040%  任务二

这样就可以很容易知道是哪一步耗时占比大了。接下来就可以有针对性的对这个一步处理逻辑进行优化。