Log4j 2:性能接近疯狂

最近,Apache社区中一位受人尊敬的成员尝试了Log4j 2并在Twitter上写道:

@TheASF #log4j2摇摇欲坠 ! 性能接近疯狂^^ http://t.co/04K6F4Xkaa

— Mark Struberg(@struberg) 2013年5月7日

(来自Mark Struberg的名言:@TheASF#log4j2摇摇欲坠!性能接近疯狂^^ http://logging.apache.org/log4j/2.x/)

在Remko Popma贡献了一些东西(现在称为“ AsyncLoggers”)之后不久便发生了。 某些人可能知道Log4j 2已经具有AsyncAppenders。 它们相似,就像您在Log4j 1和其他日志记录框架中可以找到的一样。

老实说:我对新功能并不感到兴奋,直到我阅读了有关其性能的推文并对此感到好奇。 显然,Java日志记录有许多目标。 其中: 日志记录必须和地狱一样快 。 没有人希望他的日志记录框架成为瓶颈。 当然,登录时总会有成本。 CPU必须执行一些操作。 即使您决定不编写日志语句,也正在发生某些事情。 预计日志是不可见的。

到目前为止,众所周知的日志记录框架在速度上是相似的。 基准毕竟是不可靠的。 我们已经在Apache Logging上建立了一些基准。 有时,一个日志记录框架会获胜,有时则是另一个。 但总而言之,您可以说他们都很好
您可以选择自己喜欢的任何方式。 直到获得Remko的贡献,Log4j 2变得“异常快速”。

运行一个线程的小型软件项目可能不太在乎性能。 在运行SaaS时,您根本不知道您的应用何时会吸引到您需要扩展的吸引力。 然后,您突然需要一些额外的电源。

使用Log4j 2,运行64个线程可能为您带来的日志吞吐量是同类框架的十二倍。

我们说每秒超过18,000,000条消息,而其他消息在同一环境中的发送量大约为1,500,000条或更少

我看到了图表,但简直不敢相信。 一定有问题。 我重新检查了。 我自己进行了测试。 就像这样: Log4j 2的速度非常快。

异步性能,最后阅读时间:2013年7月19日

异步性能,最后阅读时间:2013年7月19日

截至目前,我们拥有一个日志记录框架,该框架的性能比那里的其他所有日志记录框架都要好。 到目前为止,如果速度很重要,那么当我们不想使用Log4j 2时,我们需要证明我们的决定是正确的。 Log4j 2之外的所有其他内容都可能成为瓶颈和风险。 有了如此快速的日志记录框架,您甚至可以考虑比以前更多地记录生产中的日志。

最终,我给雷姆科写了一封电子邮件,问他旧的AsyncAppenders和新的异步记录器之间到底有什么区别

旧的AsynAppenders和新的AsyncLoggers之间的区别

他告诉我:“异步记录器在做两件事上与AsyncAppender有所不同,”他们试图在将日志消息传递到另一个线程之前做最少的工作,并且他们使用不同的机制在生产者和生产者之间传递信息。消费者线程。 AsyncAppender使用ArrayBlockingQueue将消息传递给写入磁盘的线程, 异步记录器使用LMAX Disruptor库 。 特别是Disruptor的性能差异很大。”

换句话说,AsyncAppender使用先进先出队列来处理消息。 但是异步记录器使用了新的东西-Disruptor。 老实说,我从未听说过。 而且,我从未想过要扩展我的日志记录框架。 当有人说“扩展系统”时,我想到了数据库,应用服务器等等,但通常不会记录日志。 在生产中,记录已关闭。 故事结局。

但是,雷姆科(Remko)考虑进行日志记录时进行扩展。

“查看异步记录器的性能测试结果,您会注意到的第一件事是,某些记录方式的伸缩性要好于其他方式。 通过更好地扩展,我的意思是当添加更多线程时,您将获得更多的吞吐量。 如果您添加的每个线程的吞吐量都增加了一个恒定值,那么您将具有线性可伸缩性。 这是非常可取的,但可能很难实现。”他写道。

“将同步与异步进行比较,您将期望任何异步机制的扩展都比同步日志记录好得多,因为您不再在生产线程中执行I / O,而且我们都知道'I / O很慢'(而且我会再说一遍)”。

是的,完全是我的理解。 我认为将某些内容发送到队列就足够了,而其他的则可以将其接收并编写消息。 该应用程序将继续运行。 雷姆科写道,这正是旧的AsyncAppender所做的:

“使用AsyncAppender,您的所有应用程序线程所需要做的就是创建一个LogEvent对象,并将其放在ArrayBlockingQueue上; 然后,使用线程将这些事件从队列中移出并完成所有耗时的工作。 即,将事件转换为字节并将这些字节写入I / O设备的工作。 由于应用程序线程不需要执行I / O,因此您希望它可以更好地扩展,这意味着添加线程将允许您记录更多事件。

如果您相信像我一样,请坐下并深呼吸。 我们错了。

他写道:“事实可能并非如此。”

“如果查看所有日志记录框架的AsyncAppenders的性能数字,就会发现,每增加一倍的线程数,每个线程的吞吐量就会减少一半。”

“因此,您的总吞吐量或多或少保持不变! 他告诉我,AsyncAppenders比同步日志记录要快,但是它们在某种意义上是相似的,即当您添加更多线程时,它们都不为您提供更多的总吞吐量。

它像锤子一样打在我身上。 基本上,而不是通过添加更多线程来提高日志记录速度,基本上是:没有。 毕竟,直到现在Appender都没有扩展。 我问雷姆科为什么会这样。

事实证明,队列并不是在线程之间传递信息的最佳数据结构。 作为标准Java库的一部分的并发队列使用锁来确保值不会被破坏并确保线程之间的数据可见性。

LMAX破坏者?

“ LMAX团队对此进行了大量研究,发现这些队列有很多锁争用。 他们发现一个有趣的事情是队列始终是满的或空的:如果生产者速度更快,则在大多数情况下您的队列将是满的(这本身可能就是一个问题)。 如果您的使用者速度足够快,则您的队列在大多数情况下将是空的。 无论哪种方式,您都将在队列的开头或结尾都有争用,生产者线程和使用者线程都想在其中更新同一字段。 为了解决这个问题,LMAX团队提出了Disruptor库,该库是用于在线程之间传递消息的无锁数据结构。 这是Disruptor和ArrayBlockingQueue之间的性能比较 : 性能比较 。”

哇。 经过这些年的Java编程,我实际上再次感觉像是初级程序员。 我错过了LMAX破坏者,甚至从未考虑使用Queue带来的性能问题。 我想知道到目前为止还没有发现什么其他性能问题。 我意识到,我不得不重新学习Java。

我问雷姆科,他怎么能找到像LMAX破坏者这样的图书馆。 我的意思是,没有人编写软件,创建队列类的实例,怀疑其性能并最终在互联网上搜索“更好的东西”。

还是真的有这种人?

“我如何发现Disruptor? 简短的答案是,这全都是错误。”他开始说道。

“好吧,也许这有点太短了,所以答案更长一些:我的一位同事写了一个小的记录器,本质上在队列中添加了带时间戳的日志消息,并带有后台线程,这些线程使这些字符串脱离了队列。并将它们写入磁盘。 他之所以这样做,是因为他需要比log4j-1.x更好的性能。 我做了一些测试,发现它更快,我不记得确切多少。 我很惊讶,因为我已经使用log4j多年了,并且从未想到过它会轻易胜过。 在那之前,我一直以为著名的库会很快,因为……说实话,我只是以为。 因此,这让我大开眼界。 但是,自定义记录器在功能上有些勉强,所以我开始四处寻找替代方案。”

“在我开始谈论Disruptor之前,我必须坦白一些东西。 最近,我回过头来查看自定义记录器比log4j-1.x快多少,但是当我测量时,它实际上要慢一些! 原来,我一直在将自定义记录器与log4j-2.0的旧beta(我认为beta3或beta4)进行比较。 这些Beta版中的AsyncAppender仍然存在性能问题(如果您好奇,则为LOG4J2-153)。 如果我将自定义记录器与log4j-1.x中的AsyncAppender进行了比较,我会发现log4j-1.x更快,并且我不会再考虑了。 但是由于犯了这个错误,我开始寻找功能更丰富的其他高性能日志记录库。 我没有找到这样的日志库,但是遇到了很多其他有趣的东西,包括Disruptor。 最终,我决定尝试将具有良好代码基础的Log4j-2与Disruptor结合使用。 结果最终被Log4j-2本身接受,其余的,正如他们所说的,已成为历史。”

“我在这里提到的一件事是彼得·劳瑞(Peter Lawrey)的编年史图书馆 。 Chronicle使用内存映射文件以极低的延迟每秒将数千万条消息写入磁盘。 还记得上面我说过的“我们都知道I / O速度很慢”吗? 纪事表明,同步I / O可以非常非常快。 ”。

“通过彼得的工作,我遇到了破坏者。 关于Disruptor的资料很多。 只是给您一些提示:

  • 马丁·福勒(Martin Fowler):LMAX
  • 特里莎(Trisha Lee)在引擎盖下的LMAX上使用 (现在略过时,但我知道的最详细的资料)
  • …像这样的视频演示

强烈建议使用Disruptor Google组。

推荐的有关Java性能的阅读材料通常是:

  • 马丁·汤普森(Martin Thompson)的“机械同情”
  • 马丁·汤普森演讲。

Martin Thompson就Java高性能计算的各个方面做了很多文章和演示。 他出色地完成了引擎盖下正在进行的复杂操作。”

阅读此电子邮件后,我的书签文件夹已满,并且我非常感谢您有很多起点来提高我对Java性能的了解。

我应该默认使用AsyncLoggers吗?

我确定我想使用新的异步记录器。 这听起来真是太棒了。 但另一方面,我有点害怕,甚至有点偏执,无法包括新的依赖项或新技术,例如新的Log4j 2 Async Loggers。 我问雷姆科,他是否默认使用新功能,还是仅在少数有限的用例中启用它们。

我默认使用异步记录器 ,是的。”他写道。 “一个用例的时候,你会_not_要使用异步日志记录是当您使用日志记录审计目的。 在这种情况下,记录错误是您的应用程序需要了解和处理的问题。 我相信大多数应用程序都是不同的,因为它们不太在乎记录错误。 大多数应用程序都不想在发生日志记录异常时停止,实际上,他们甚至都不希望知道它。 默认情况下,Log4j-2.0中的追加器将抑制异常,因此应用程序无需尝试/捕获每个日志语句。 如果这是您的用法,那么使用异步记录器将不会造成任何损失,因此您只能获得收益,即性能得到改善。”

“我应该提到的一个不错的小细节是,异步记录器和异步附加器都修复了一些在Log4j-1.x中一直困扰我的东西,即它们将在记录队列中的最后一个事件后刷新缓冲区 。 对于Log4j-1.x,如果使用缓冲的I / O,则通常看不到最后几个日志事件,因为它们仍卡在内存缓冲区中。 唯一的选择是将InstantFlush设置为true,这将在每个单个日志事件上强制使用磁盘I / O,并会影响性能。 使用Log4j-2.0中的Async Loggers和Appenders,您的日志语句都被刷新到磁盘上,因此它们始终可见,但这是以非常有效的方式发生的。”

登录使用Log4js AsyncLoggers冒险吗?

但是考虑到Log4j-1存在严重的线程问题,并且现代世界一直在使用云计算和集群来扩展其应用程序, 异步日志记录不是某种额外的风险吗? 还是安全? 我知道我的问题听起来像是决策者而不是开发人员的问题。 但是整个LMAX对我来说还是那么新,并且由于我保留了旧的而且非常丑陋的Log4j 1代码,所以我只需要问一下。

雷姆科:“那里有很多问题。 首先,从并发角度看,Log4j-2是否比Log4j-1.x安全? 我相信是这样。 Log4j-2团队付出了巨大的努力来支持多线程应用程序,并且异步记录器只是该项目的一个非常新的且相对较小的功能。 与Log4j-1.x相比,Log4j-2使用的粒度锁定更多,并且在结构上更简单,这将导致更少的问题,并且出现的任何问题都将更易于解决。”

“另一方面,Log4j-2仍处于测试阶段,并且仍在积极开发中,尽管最近我认为大多数精力都花在了修复问题和捆绑松散的末端上,而不是添加新功能。 我相信它足够稳定以供生产使用。 如果出于性能或其他原因考虑使用Log4j-2,我建议您进行尽职调查和测试,就像在项目中采用任何其他第三方库之前一样。”

(旁注:可以很快找到Log4j2的稳定版本,很可能是2013年秋天)。

对我来说听起来不错。 是的,尽管我个人没有在Log4j 2存储库中编写代码,但从我对项目的观察中我可以完全同意这一点。

“我看到的另一个问题是: 异步日志记录比同步日志记录有风险吗? 我不这么认为,实际上,如果您的应用程序是多线程的,则情况可能恰恰相反:一旦将日志事件移交给执行I / O的使用者线程,则只有一个线程在处理布局,附加程序以及所有其他与日志记录相关的组件。 因此,在移交之后,您将成为单线程的,并且您无需再担心任何线程问题,例如死锁和活动性等。”

“您可以更进一步,使您的业务逻辑完全单线程化,并使用干扰器进行所有I / O或与外部系统的通信。 没有锁争用的单线程业务逻辑可以非常快。 LMAX的结果(600万笔事务/秒,延迟少于10毫秒)是不言而喻的。”

阅读雷姆科的信息,我学到了三件事。

  • 首先,我必须学习有关Java性能的更多信息。
  • 其次,我绝对想让我的应用程序使用Log4j2。首先,我将在经常使用的Struts 2应用程序中启用它。
  • 第三,使用LMAX Disruptor的Web应用程序框架可能会让我们震惊。

我要非常感谢您和一个拥抱Remko Popma,感谢他们回答我的问题并与我一起撰写此博客文章。 所有错误都是我自己的。

雷姆波波玛

雷姆科波马 二十年前,雷姆科(Remko)来到日本,以提高围棋比赛的水平。 不知何故他再也没有回来。 Remko开始为日本软件公司进行软件开发,短暂地担任自由开发人员,与日本合作伙伴一起经营了一家软件公司,现在正领导瑞穗证券IT的算法交易开发。 他与妻子Tomoe和儿子Tobias一起住在东京。

参考: Log4j 2: PHP和Java Entwickler博客上的JCG合作伙伴 Christian Grobmeier的性能接近疯狂 。

翻译自: https://www.javacodegeeks.com/2013/07/log4j-2-performance-close-to-insane.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368276.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Uncaught SyntaxError: Invalid Unicode escape sequence异常处理

今天碰到一个问题&#xff0c;页面报错&#xff1a;Uncaught SyntaxError: Invalid Unicode escape sequence ,{index:operate,name:operate,label:<s:text name"com.vrv.cems.ptp.installSoft.operate"></s:text>,width:getPerWidth(0.1),formatter:fun…

26、jQuery

一. jQuery简介 (一) jQuery是什么&#xff1a; 是一个javascript代码仓库 是一个快速的简洁的javascript框架&#xff0c;可以简化查询DOM对象、处理事件、制作动画、处理Ajax交互过程。 (二) jQuery优势 体积小&#xff0c;使用灵巧(只需引入一个js文件)方便的选择页面元素(模…

python做自动化如何定位动态元素_python-web自动化-元素定位

# -*- coding:utf-8 -*-from selenium import webdriverfrom selenium.webdriver.common.by import By# 打开Chrome浏览器和百度网页driver webdriver.Chrome()driver.get(https://www.baidu.com/)# 元素定位&#xff1a;id绝对唯一&#xff0c;name其次# id 定位‘百度首页输…

玩转ajax

1.什么是ajax&#xff1f; Ajax 是 Asynchronous JavaScript and XML&#xff08;以及 DHTML 等&#xff09;的缩写。 2.ajax需要什么基础? HTML 用于建立 Web 表单并确定应用程序其他部分使用的字段。 JavaScript 代码是运行 Ajax 应用程序的核心代码&#xff0c;帮助改…

Spring MVC:验证器和@InitBinder

很难想象没有针对用户数据的验证逻辑的Web应用程序。 几乎所有用户的数据都有一些限制&#xff0c;例如&#xff0c;出生日期应由日&#xff0c;月&#xff0c;年等组成。SpringMVC拥有自己的数据验证解决方案&#xff0c;并且在Validator界面的帮助下可用。 Spring MVC Vali…

ADB 调试

1、adb简介 adb的全称为Android Debug Bridge&#xff0c;就是起到调试桥的作用。通过adb我们可以在Eclipse中方面通过DDMS来调试Android程序&#xff0c;说白了就是debug工具。adb的工作方式比较特殊&#xff0c;采用监听Socket TCP 5554等端口的方式让IDE和Qemu通讯&#xff…

python 函数式编程尾递归优化 day16

函数编程的特征&#xff1a; 1不可变&#xff1a;不用变量保存状态&#xff0c;不修改变量 #非函数式 a 1 def incr_test1():global a#一旦更改全局变量后后面再调用a就容易乱a 1return a incr_test1() print(a) def bar():print(from bar) def foo():print(from foo)return …

java英文试题_Java试题及答案英文版

1&#xff0e;Which two demonstrate an “is a” relationship? (Choose Two)A. public interface Person { }public class Employee extends Person { }B. public interface Shape { }public class Employee extends Sha pe { }C. public interface Color { }public class E…

margin折叠-从子元素margin-top影响父元素引出的问题

正在做一个手机端电商项目&#xff0c;顶部导航栈的布局是一个div包含一个子div&#xff0c;如果给在正常文档流中的子div一个垂直margin-top&#xff0c;神奇的现象出现了&#xff0c;两父子元素的边距没变&#xff0c;但父div跟着一起往下走了&#xff01; html代码&#xff…

js时间转换

window.οnlοadfunction(){setInterval("mytime()",1000); } function mytime(){document.getElementById("time").innerHTML fmtDate(new Date()); } function fmtDate(obj){var date new Date(obj);var y 1900date.getYear();var m "0"(…

Lambdas:来到您附近的Java 8!

什么是Lambda&#xff1f; Lambda表达式是一种匿名函数&#xff0c;可以在方法中内联编写&#xff0c;并且可以在使用表达式的任何地方使用。 有时您可能会发现它们被称为闭包&#xff0c;尽管我在下面解释了对该参考的一些注意事项。 像普通的Java方法一样&#xff0c;它具有参…

CPU-内存-IO-网络调优

一、关于CPU 中央处理器调优 1、 CPU处理方式&#xff1a; 批处理&#xff0c;顺序处理请求。(切换次数少&#xff0c;吞吐量大)分时处理。(如同"独占"&#xff0c;吞吐量小)(时间片&#xff0c;把请求分为一个一个的时间片&#xff0c;一片一片的分给CPU处理)我们现…

spark抽取mysql数据到hive_使用spark将内存中的数据写入到hive表中

使用spark将内存中的数据写入到hive表中hive-site.xmlhive.metastore.uristhrift://master:9083Thrift URI for the remote metastore. Used by metastore client to connect to remote metastore.javax.jdo.option.ConnectionURLjdbc:mysql://master:3306/metastore?createDa…

使用Merge存储引擎实现MySQL分表

使用Merge存储引擎实现MySQL分表 学习了&#xff1a;https://www.cnblogs.com/try-better-tomorrow/p/4987620.html https://www.cnblogs.com/xbq8080/p/6628034.html http://blog.csdn.net/java_bruce/article/details/71077985 https://www.cnblogs.com/johnnyzhang/articles…

Flexible 弹性盒子模型之CSS flex-shrink 属性

实例 让第二个元素收缩到其他元素的三分之一&#xff1a; 效果预览 div:nth-of-type(2){flex-shrink:3;}浏览器支持 表格中的数字表示支持该属性的第一个浏览器的版本号。 紧跟在 -webkit-, -ms- 或 -moz- 后的数字为支持该前缀属性的第一个版本。 属性 flex-shrink29.021.…

使用Base64

为什么要使用Base64&#xff1f;在设计这个编码的时候&#xff0c;我想设计人员最主要考虑了3个问题&#xff1a; 1.是否加密&#xff1f; 2.加密算法复杂程度和效率 3.如何处理传输&#xff1f; 加密是肯定的&#xff0c;但是加密的目的不是让用户发送非常安全的Email。这…

idea 新建的java项目没发run_IntelliJ IDEA创建普通的Java 项目及创建 Java 文件并运行的教程...

最近突然看到这篇几年前随手记录的文章&#xff0c;居然浏览量那么高。看来很多小伙伴也开始从 Eclipse 转到 IDEA&#xff0c;这里为了让大家更好的掌握 IDEA 的使用&#xff0c;我建议大家可以看看下面这个 IDEA 教程。首先&#xff0c;确保 IDEA 软件正确安装完成&#xff0…

如何在Maven中运行Ant目标?

maven-antrun-plugin允许我们在各种maven构建阶段中运行ant目标。 我将专门为具有开发环境的开发人员解释maven-antrun-plugin的非常实际的用法。 通常&#xff0c;使用maven build&#xff0c;您会将项目捆绑到war文件或ear文件中。 您可以使用maven-antrun-plugin直接将此w…

PHP基本知识

php为服务端的脚本语言&#xff0c;它的使用需要打开WAMP的开发环境&#xff0c;php也可以用制作网页的DW制作&#xff0c;文件需保存在wamp文件夹内的www文件夹里面。 嵌入php代码所使用的标签&#xff1a;<?php ?>&#xff1b; 运行php条件&#xff1a; 1.电脑上需…

java semaphore 等待_Java并发编程系列之Semaphore详解

简单介绍我们以饭店为例&#xff0c;假设饭店只有三个座位&#xff0c;一开始三个座位都是空的。这时如果同时来了三个客人&#xff0c;服务员人允许他们进去用餐&#xff0c;然后对外说暂无座位。后来的客人必须在门口等待&#xff0c;直到有客人离开。这时&#xff0c;如果有…