精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
作者 | 正文 | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2009-01-15
最后修改:2009-01-19
近日在写多线程方面的东西,需要对多线程进行日志监控就重新翻出了log4j,看到了log4j下居然还有一个AsyncAppender,异步记日志?觉得挺不错,网上搜了一下也有一些讨论,JavaEye上也有很多讨论。但是这个AsyncAppender到底能否提升日志性能呢?我们还是先看看log4j本身文档里的性能测试说明吧,详细测试数据见如下URL:http://www.ingrid.org/jajakarta/log4j/jakarta-log4j-1.1.3/docs/api/org/apache/log4j/performance/Logging.html
由此可见AsyncAppender虽然是异步的,但是并不能提升性能,为什么呢?何谓异步?异步就是另外开了个线程用来专门记录日志,然而既然引入了多线程,线程间的同步开销就不能不考虑了,看AsyncAppender的源代码中到处充斥着synchronized就能看到了。
用独立线程处理日志会引入以下几个问题:
由此的需要讨论就是,为什么要使用异步?何时使用异步?如何使用异步?我们先来看同步和异步到底有何不同:
同步情况各线程直接获得输出流进行输出(线程间不需要同步)。 异步情况
众所周知,磁盘IO操作、网络IO操作、JDBC操作等都是非常耗时的,日志输出的主要性能瓶颈也就是在写文件、写网络、写JDBC的时候。日志是肯定要记的,而要采用异步方式记,也就只有将这些耗时操作从主线程当中分离出去才能真正的实现性能提升,也只有在线程间同步开销小于耗时操作时使用异步方式才真正有效!现在我们接着分别来看看这几种记录日志的方式。 将日志记录到本地文件同样都是写本地文件Log4j本身有一个buffer处理入库,采用异步方式并不一定能提高性能(主要是如何配置好缓存大小);而线程间的同步开销则是非常大的!因此在使用本地文件记录日志时不建议使用异步方式。 将日志记录到JMSJMS本身是支持异步消息的,如果不考虑JMS消息创建的开销,也不建议使用异步方式。 将日子记录到SOCKET将日志通过Socket发送,纯网络IO操作不需要反馈,因此也不会耗时 将日志记录到数据库众所周知JDBC是几种方式中最耗时的:网络、磁盘、数据库事务,都使JDBC操作异常的耗时,在这里采用异步方式入库倒是一个不错的选择。 将日志记录到SMTP同JDBC
性能测试在同步和异步方式下,同时起1000个线程,分别测试记录到文件和数据库中的时间消耗,每类测试连测5遍避免误差。
测试环境1、WINDOWS XP SP2、JDK 1.5、ORACLE 9i2(本地)、log4j-1.2.14.jar 2、MutiTest.java用来测试同步方式,读取配置文件:log4j.properties MutiTestAsyncAppender.java用来测试异步方式,读取配置文件:log4j.xml 3、每次测试先删除日志文件或清空表,确保测试独立性
测试结果如下:
结论由以上测试结果可以得出异步方式记录日志并不是什么情况下都能提升性能的,相反由于线程间的同步开销,甚至可能降低性能;只有像在JDBC操作或是SMTP之类的记录耗时比较长的情况下,使用异步入库方式才是个好选择。
PS:第一次写这么长的文章,欢迎大家指摘。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2009-12-10
实际数据测试,有说服力
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
发表时间:2009-12-10
很受用的一篇文章!真正动手测试过才是正道,并非所有东西异步化都是提高效率。
就log这块,其实最关键就是减少I/O, 我目前优化的日志系统从这2个方面做: 1. 优化logger对象结构,减少不必要的继承关系,或者是采用#log4j.additivity.sqllog=false 尽量考虑让大多数日志内容只打到一个文件,而不是所有继承树上的日志文件都去记一份, O(n)的提高。 2.有框架记录重复性的日志,进而约定程序员控制自己的日志内容频率、每条log的长度及合理性。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
返回顶楼 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
浏览 4712 次