最近在做性能优化,然后在监测慢 API 与 sql 时遇到了一些问题,监测慢 API,即统计 API 耗时时用了切面编程,但是默认情况下,事务的顺序比他高,然后但凡是开启了事务的接口,统计出来的耗时都不准,因为事务提交没统计,等于 sql 耗时没统计。添加 @Order 后解决了,但是 统计 慢 sql 时,又遇到了坑!
其实,统计慢 sql 无非就下面几行关键配置:
slow_query_log = 1 slow_query_log_file = /var/log/mysql/mariadb-slow.log long_query_time = 1 log-queries-not-using-indexes = 1 log_throttle_queries_not_using_indexes = 1 # 发生几次后记录 log_slow_rate_limit = 1 min_examined_row_limit = 0 log_slow_verbosity = query_plan,explain log_output = table
一定要注意这里的 log_slow_rate_limit,我最初设置为了 1000,无论如何都记录不到。。。。
此外,我使用的是 docker,/var/log/mysql 这个目录不存在,mysql 也不自动创建,然后手动创建了,创建后修改下所有者即可!最后,说下 另一个问题,使用 切面编程统计 API 耗时!相关代码可能如下:
@Aspect @Component public class ServiceAspect { public static final String POINT = "execution(* xxxxx)"; @Around(POINT) public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable { Object result = null; try { long startTime = System.currentTimeMillis(); result = joinPoint.proceed(); long costTime = System.currentTimeMillis() - startTime; printLog(joinPoint, joinPoint.getArgs(), costTime, result); } catch (Throwable e) { } return result; } }
由于没有使用 @Order 指定执行顺序,导致事务的切面类先执行,然后我写的类执行,我们知道,切面类是同心圆,先执行的后结束,于是我的切面类在事务提交前结束了,即没有统计到sql的执行时间。。。。解决办法也很简单,改为类似如下这样:
@Aspect @Order(1) // 越小越先执行,如果有多个切面类,务必确认 @Order 的顺序,切面类是同心圆,最先执行的最后结束! @Component public class ServiceAspect {
这里,如果不指定 Order 则默认是 int 的最大值!所以建议开发中,务必指定 Order 以避免类似的错误。