`

日志优化

    博客分类:
  • JAVA
 
阅读更多

在任何系统中,日志都是非常重要的组成部分,它是反映系统运行情况的重要依据,也是排查问题时的必要线索。绝大多数人都认可日志的重要性,但是又有多少人仔细想过该怎么打日志,日志对性能的影响究竟有多大呢?今天就让我们来聊聊Java日志性能那些事。

说到Java日志,大家肯定都会说要选择合理的日志级别、合理控制日志内容,但是这仅是万里长征第一步……哪怕一些DEBUG级别的日志在生产环境中不会输出到文件中,也可能带来不小的开销。我们撇开判断和方法调用的开销,在Log4J 2.x的性能文档中有这样一组对比:

 logger.debug("Entry number: " + i + " is " +  String.valueOf(entry[i])); 
 logger.debug("Entry number: {} is {}", i, entry[i]);

上面两条语句在日志输出上的效果是一样的,但是在关闭DEBUG日志时,它们的开销就不一样了,主要的影响在于字符串转换和字符串拼接上,无论是否生效,前者都会将变量转换为字符串并进行拼接,而后者则只会在需要时执行这些操作。Log4J官方的测试结论是两者在性能上能相差两个数量级。试想一下,如果某个对象的toString()方法里用了ToStringBuilder来反射输出几十个属性时,这时能省下多少资源。

 

因此,某些仍在使用Log4J 1.x或Apache Commons Logging(它们不支持{}模板的写法)的公司都会有相应的编码规范,要求在一定级别的日志(比如DEBUGINFO)输出前增加判断:

if (logger.isDebugEnabled()) { 
    logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i])); 
}

除了日志级别和日志消息,通常在日志中还会包含一些其他信息,比如日期、线程名、类信息、MDC变量等等,根据Takipi的测试,如果在日志中加入class,性能会急剧下降,比起LogBack的默认配置,吞吐量的降幅在6成左右。如果一定要打印类信息,可以考虑用类名来命名Logger

在分布式系统中,一个请求可能会经过多个不同的子系统,这时最好生成一个UUID附在请求中,每个子系统在打印日志时都将该UUID放在MDC里,便于后续查询相关的日志。《The Ultimate Guide: 5 Methods For Debugging Production Servers At Scale》一文中就如何在生产环境中进行调试给出了不少建议,当中好几条是关于日志的,这就是其中之一。另一条建议是记录下所有未被捕获的日志,其实抛出异常有开销,记录异常同样会带来一定的开销,主要原因是Throwable类的fillInStackTrace方法默认是同步的:

public synchronized native Throwable fillInStackTrace();

一般使用logger.error都会打出异常的堆栈,如果对吞吐量有一定要求,在情况运行时可以考虑覆盖该方法,去掉synchronized native,直接返回实例本身。

聊完日志内容,再来看看Appender。在Java中,说起IO操作大家都会想起NIO,到了JDK 7还有了AIO,至少都知道读写加个Buffer,日志也是如此,同步写的Appender在高并发大流量的系统里多少有些力不从心,这时就该使用AsyncAppender了,同样是使用LogBack:

在10线程并发下,输出200字符的INFO日志,AsyncAppender的吞吐量最高能是FileAppender的3.7倍。在不丢失日志的情况下,同样使用AsyncAppender,队列长度对性能也会有一定影响。

如果使用Log4J 2.x,那么除了有AsyncAppender,还可以考虑性能更高的异步Logger,由于底层用了Disruptor,没有锁的开销,性能更为惊人。根据Log4J 2.x的官方测试,同样使用Log4J 2.x:

64线程下,异步Logger比异步Appender快12倍,比同步Logger68倍。

同样是异步,不同的库之间也会有差异:

同等硬件环境下,Log4J 2.x全部使用异步Logger会比LogBack的AsyncAppender快12倍,比Log4J 1.x的异步Appender快19倍。

(点击放大图像)

Log4J 2.x的异步Logger性能强悍,但也有不同的声音,觉得这只是个看上去很优雅,只能当成一个玩具。关于这个问题,还是留给读者自己来思考吧。

如果一定要用同步的Appender,那么可以考虑使用ConsoleAppender,然后将STDOUT重定向到文件里,这样大约也能有10%左右的性能提升。

大部分生产系统都是集群部署,对于分布在不同服务器上的日志,用Logstash之类的工具收集就好了。很多时候还会在单机上部署多实例以便充分利用服务器资源,这时千万不要贪图日志监控或者日志查询方便,将多个实例的日志写到同一个日志文件中,虽然LogBack提供了prudent模式,能够让多个JVM往同一个文件里写日志,但此种方式对性能同样也有影响,大约会使性能降低10%。

如果对同一个日志文件有大量的写需求,可以考虑拆分日志到不同的文件,做法之一是添加多个Appender,同时修改代码,不同的情况使用不同Logger;LogBack提供了SiftingAppender,可以直接根据MDC的内容拆分日志,Jetty的教程中就有根据host来拆分日志的范例,而根据Takipi的测试,SiftingAppender的性能会随着拆分文件数的增长一同提升,当拆分为4个文件时,10并发下SiftingAppender的吞吐量约是FileAppender的3倍多。

看了上面这么多的数据,不知您是否觉得自己的日志有不少改进的余地,您还没有把系统优化到极致,亦或者您还有其他日志优化的方法,不妨分享给大家。


感谢丁晓昀对本文的审校。

 

文章出处:http://www.infoq.com/cn/articles/things-of-java-log-performance

分享到:
评论

相关推荐

    Unity3D 日志优化 写入本地性能优化

    Unity3D 日志优化 使用参考 Unity3D 日志优化 使用参考 Unity3D 日志优化 使用参考 https://blog.csdn.net/nicepainkiller/article/details/84958804 ...

    Oracle数据库重做日志优化设计研究.pdf

    总的来说,Oracle数据库的重做日志优化设计需要综合考虑日志文件的大小、数量、分布以及I/O性能,以确保数据库的高效运行和数据的可靠恢复。通过合理的规划和持续的监控,可以最大化地提升系统的稳定性和性能。

    看路由器日志,优化BT下载.pdf

    接下来,我们来探讨如何根据路由器日志优化BT下载: 1. 路由器性能评估:通过查看性能日志,可以评估当前路由器在处理BT下载时的性能状况。如果发现CPU使用率过高或内存不足,可能需要升级路由器硬件或调整路由策略...

    去掉没必要的日志,避免影响调试

    这些可能是代码或配置文件的修改记录,它们可能涉及到日志优化的具体实现,比如修改日志输出的逻辑,添加或移除了某些日志打印语句,或者调整了日志级别设置。具体的优化措施需要结合代码内容来分析。 总的来说,...

    关于SQLServer事务日志的问题汇总

    ### 事务日志优化策略 为了高效管理事务日志,建议采取以下策略: - 定期分析事务日志的增长趋势,根据需求调整日志文件的初始大小和最大大小。 - 使用SQL Server的维护计划,定期执行事务日志备份和日志文件的...

    Tomcat性能优化

    6. **日志优化**:关闭不必要的日志输出,或者配置异步日志,减少日志写入对主线程的影响。 7. **类加载机制**:理解Tomcat的类加载机制,避免类加载冲突,提高类加载效率。 8. **减少应用启动时间**:通过预加载...

    redis集群, tomcat优化以及 MySQL5.6优化

    3. 日志优化:减少日志输出,降低 I/O 开销,或启用异步日志写入,避免阻塞主线程。 4. Web 应用优化:合并和压缩静态资源,减少 HTTP 请求次数;使用 GZIP 压缩,减小传输体积;优化数据库访问,避免过多的 SQL ...

    android日志抓取

    9. **日志优化**:在开发过程中,合理地使用日志级别,避免过多的DEBUG日志影响应用性能,同时在发布版本时考虑移除或禁用不必要的日志输出。 总的来说,Android日志抓取是开发者日常工作中不可或缺的部分,它能...

    tomcat 启动优化和并发并发优化配置.rar

    4. **日志优化**:合理配置日志级别,避免过度的日志输出影响性能。 总结,Tomcat的启动优化和并发优化是一个综合性的过程,涉及到JVM参数、服务器配置、应用代码等多个层面。开发者需根据实际场景进行调整,以达到...

    Tomcat、JDK优化配置

    4. **日志优化**:合理配置日志级别,避免不必要的日志输出影响性能。可以使用异步日志框架如Log4j2以减少I/O阻塞。 5. **部署优化**:减少应用的启动时间,可以通过预编译JSP页面、启用热部署(-Dorg.apache....

    oracle数据库整体优化方案全

    本文将详细介绍一种全面的Oracle数据库优化方案,涵盖监控、磁盘I/O优化、回滚段优化、Redo日志优化、系统全局区(SGA)优化等多个方面。 #### 二、监控数据库性能 监控是优化的基础。为了准确了解Oracle数据库的...

    Postgres数据库基于持久内存的优化探索.pptx

    1. WAL 日志优化:WAL(Write Ahead Log)日志是Postgres数据库的关键组件,用于确保数据库的事务完整性。使用PM可以将WAL日志写入到持久内存中,从而提高数据库的写入性能。 2. 表空间优化:Postgres数据库的表...

    Tomcat7优化

    五、日志优化 1. 日志级别:根据需要调整日志级别,避免过多的日志输出影响性能。 2. 使用异步日志框架,如Logback的AsyncAppender,减少日志记录对主线程的影响。 六、安全配置 1. 禁用不必要的服务和协议,如...

    IBM DB2数据库性能优化视频.rar

    │ │ 第5周 日志优化.mp4 │ └ 第5周 日志优化.pdf ├ 第06周 DB2运维工具优化 │ │ 第6周 DB2运维工具优化.mp4 │ └ 第6周 运维工具优化.pdf ├ 第07周 锁机制深入解析 │ │ 第7周 锁机制深入解析.mp4 │ └ ...

    weblogic10性能优化及相关技巧

    日志优化则关注日志的记录、存储和查询效率,优化日志配置可以减少系统资源的占用,提高系统的运行效率。 最后,对于WebLogic的日常监控和维护,可以通过管理控制台来监测WebLogic的运行情况。而忘记管理控制台密码...

    参考资料-生产日志统计表.zip

    例如,分析慢查询日志优化数据库性能,或根据API调用日志调整服务架构。 9. 问题定位: 当系统出现问题时,日志是排查问题的关键依据。通过查找相关错误信息,可以定位问题发生的时间、位置,以及可能的原因。 10...

    Oracle数据库性能优化

    本文将深入探讨Oracle数据库性能优化的策略与实践,涵盖数据库磁盘I/O优化、回滚段优化、Redo日志优化、系统全局区(SGA)调整以及数据库对象优化等关键领域。 #### 数据库磁盘I/O优化 磁盘I/O效率直接影响数据库...

    SYSBIOS系统开发入门-11-1-日志 上.rar

    3. **日志优化** - **性能影响**:日志输出可能会对系统性能产生影响,因此在不影响关键任务的情况下,应合理设计日志策略,例如使用异步日志输出,或者在特定条件下才启用日志。 - **空间限制**:在资源受限的...

    Jboss性能优化整合

    9. **日志优化**:控制日志输出级别,减少不必要的日志输出,可以显著提升Jboss的运行效率。 10. **持久层优化**:合理选择和配置ORM框架(如Hibernate),避免N+1查询问题,优化SQL语句,使用存储过程等,可以大大...

    Java程序性能优化 让你的Java程序更快、更稳定

    7. **日志优化**:日志输出应有控制,避免在生产环境中输出过多的日志,影响程序性能。可以使用日志级别(如DEBUG、INFO、WARN)来控制,并考虑使用异步日志记录,以降低I/O阻塞。 8. **监控与诊断**:使用工具(如...

Global site tag (gtag.js) - Google Analytics