服务日志性能调优,由log引出的巨坑

1、去掉不必要的异常堆栈打印

明显知道的异常,就不要打印堆栈,省点性能吧,任何事+高并发,意义就不一样了:)

try {
    System.out.println(Integer.parseInt(number) + 100);
} catch (Exception e) {
    // 改进前
    log.error("parse int error : " + number, e);
    // 改进后
    log.error("parse int error : " + number);
}

如果Integer.parseInt发生异常,导致异常原因肯定是出入的number不合法,在这种情况下,打印异常堆栈完全没有必要,可以去掉堆栈的打印。

2、将堆栈信息转换为字符串再打印

public static String stacktraceToString(Throwable throwable) {
    StringWriter stringWriter = new StringWriter();
    throwable.printStackTrace(new PrintWriter(stringWriter));
    return stringWriter.toString();
}

log.error 得出的堆栈信息会更加完善,JDK 的版本,Class 的路径信息,jar 包中的类还会打印 jar 的名称和版本信息,这些都是去加载类反射得来的信息,极大的损耗性能。

调用 stacktraceToString 将异常堆栈转换为字符串,相对来说,确实了一些版本和 jar 的元数据信息,此时需要你自己决策取舍,到底是否有必要打印出这些信息(比如类冲突排查基于版本还是很有用的)。

3、禁用反射优化

使用 Log4j 打印堆栈信息,如果堆栈中有反射优化生成的动态代理类,这个代理类不能被其它的Classloader加载,这个时候打印堆栈,会严重影响执行效率。但是禁用反射优化也会有副作用,导致反射执行的效率降低。

4、异步打印日志

生产环境,尤其是 QPS 高的服务,一定要开启异步打印,当然开启异步打印,有一定丢失日志的可能,比如服务器强行“杀死”,这也是一个取舍的过程。

5、日志的输出格式

我们看戏日志输出格式区别

// 格式1
[%d{yyyy/MM/dd HH:mm:ss.SSS}[%X{traceId}] %t [%p] %C{1} (%F:%M:%L) %msg%n

// 格式2
[%d{yy-MM-dd.HH:mm:ss.SSS}] [%thread]  [%-5p %-22c{0} -] %m%n

官网也有明确的性能对比提示,如果使用了如下字段输出,将极大的损耗性能

 %C or $class, %F or %file, %l or %location, %L or %line, %M or %method

服务日志性能调优,由log引出的巨坑

log4j 为了拿到函数名称和行号信息,利用了异常机制,首先抛出一个异常,之后捕获异常并打印出异常信息的堆栈内容,再从堆栈内容中解析出行号。而实现源码中增加了锁的获取及解析过程,高并发下,性能损耗可想而知。

如下是比较影响性能的参数配置,请大家酌情配置:

  • %C - 调用者的类名(速度慢,不推荐使用)
  • %F - 调用者的文件名(速度极慢,不推荐使用)
  • %l - 调用者的函数名、文件名、行号(极度不推荐,非常耗性能)
  • %L - 调用者的行号(速度极慢,不推荐使用)
  • %M - 调用者的函数名(速度极慢,不推荐使用)

解决方案——日志级别动态调整

项目代码需要打印大量 INFO级别日志,以支持问题定位及测试排查等。但这些大量的 INFO日志对生产环境是无效的,大量的日志会吃掉 CPU 性能,此时需要能动态调整日志级别,既满足可随时查看 INFO日志,又能满足不需要时可动态关闭,不影响服务性能需要。

方案:结合 Apollo 及 log4j2 特性,从 api层面,动态且细粒度的控制全局或单个 Class 文件内的日志级别。优势是随时生效,生产排查问题,可指定打开单个 class 文件日志级别,排查完后可随时关闭。

限于本篇篇幅,具体实现代码就不贴出了,其实实现很简单,就是巧妙的运用 Apollo 的动态通知机制去重置日志级别,如果大家感兴趣的话,可以私信或者留言我,我开一篇文章专门来详细讲解如何实现。

总结与展望

本篇带你了解了日志在日常软件服务中常见的问题,以及对应的解决方法。切记,简单的东西 + 高并发 = 不简单!要对生产保持敬畏之心!

文章源自  https://www.cnblogs.com/gugujifly/p/16658733.html

上一页12下一页


留言