apache.camel_Apache Camel 3.1 –更多骆驼核心优化(第2部分)

apache.camel

我以前曾在博客中介绍我们在下一个Camel 3.1版本(第1部分)中所做的优化 。

今天,我想发布大约4周后的状态更新。

我们集中在三个方面优化骆驼核心:

  • 不必要的对象分配
  • 不必要的方法调用
  • 提高绩效

换句话说,我们使Camel创建更少的对象,调用更少的方法并提高路由过程中的性能。

为了帮助识别骆驼核心中的这些问题,我们使用了一条简单的骆驼路线:

来自timer:foo

记录:foo

其他时候,我们专注于更长的路线:

来自timer:foo

记录:foo1

记录:foo2

记录:foo3

登录:fooN

或关注bean组件:

来自timer:foo

到bean:foo

等等。 我们还为计时器组件添加了一个不包含元数据的选项,因此消息不包含任何正文,标头或交换属性。 这使我们可以专注于纯路由引擎及其开销。

因此,所有这些共同帮助确定了许多较小的改进点,共同取得了巨大的成功。

tl:dr –显示数字

好吧,让我们先发布一些数字,然后再详细说明已完成的工作。

对象分配–(5分钟采样)

骆驼2.25 2.9 M创建对象

骆驼3.0 55 M对象创建

骆驼3.1 1.8 M对象创建

好的,我们必须承认Camel 3.0在路由过程中存在过多的对象分配问题。 没有内存泄漏,但是会创建许多不必要的对象。 我将在下面详细说明原因。

但是,有趣的是骆驼2.25和3.1之间的增益(创建的对象减少40%)。

方法调用–(5分钟采样)

骆驼2.25 139种不同的骆驼使用方法

骆驼3.0 167种不同的骆驼使用方法

Camel 3.1使用84种不同的Camel方法

上表列出了Camel在路由过程中从Camel调用的方法数量。 数据不包括JDK中的所有方法。 由于我们无法优化它们,但是我们可以优化Camel源代码。

从表中可以看出,我们已有改进。 骆驼3.1的使用率不到3.0的一半,比骆驼2.2.5的使用率低40%。

骆驼3.0

好的,因此Camel 3.0在使用过多内存方面存在问题。 一个重要的原因是新的React式执行器现在可以通过事件循环执行路由中的每个步骤,方法是将任务移交给队列,并让工作人员执行任务。 因此,此切换现在需要创建其他对象并将任务存储在队列等中。

最大的胜利是避免创建TRACE日志消息,不幸的是,无论是否启用TRACE日志记录级别,始终都会创建该消息。 另一个大胜利是避免使用子元素创建路由过程的toString表示形式。 取而代之的是,骆驼现在只输出进程的id,这是一个快速的操作,并且不分配新对象。

另一个问题是使用java.util.stream的新代码。 这既是祝福,也是诅咒(主要是对快速代码的诅咒)。 因此,通过使用普通的for循环,if结构并在核心路由引擎的关键部分避免使用java.util.stream,我们减少了对象分配。

Camel 3也是高度模块化的,例如,在Camel 2.x中,我们将所有类都放在同一类路径中,并且可以使用instanceof检查。 因此,在Camel 3中,我们有一些代码在执行此类检查时表现很差(再次是Java util流)。

另一个问题是被动执行器,它使用LinkedList作为队列。 因此,如果您有任务进入队列并且工作人员以相同的速度处理它们,因此队列为空/耗尽,那么LinkedList的性能会很差,因为它会不断地分配/释放对象。 通过切换到预分配大小为16的ArrayQueue,则队列中始终有任务空间,并且不会发生分配/取消分配。

还有更多优化,但上面提到的优化可能是最大的问题。 然后,许多较小的优化组合在一起。

许多较小的优化

Camel的UUID生成器正在使用一些字符串连接,这会增加成本。 我们减少了在消息和工作单元中生成UUID的需求,因此每次交换仅生成1个。

骆驼路由引擎中的内部建议(建议= AOP之前/之后)。 这些建议中的一些具有从前到后都需要保留的状态,这意味着需要存储对象。 在我们为所有建议分配一个数组之前,即使对于那些没有状态的建议也是如此,因此会存储一个null。 现在,我们仅分配具有状态的建议的确切数目的数组。 (非常小的胜利,例如object [6] vs object [2]等,但这是在骆驼路线中的每一步发生的,所以加起来就是。) 另一个胜利是,如果不需要内部路由处理器,则避免在UnitOfWork周围进行AOP。 这避免了额外的方法调用,并为after任务分配了一个回调对象。 由于所有这些都发生在路由的每个步骤中,因此是一个很好的改进。

一些最常用的EIP已经过优化。 例如

允许您使用其他MEP将消息发送到端点(但是很少使用)。 现在,EIP会检测到此情况,并避免创建用于恢复MEP的回调对象。 管道EIP(例如,当您执行->到-> to时)也对使用索引计数器而不是java.util.Iterator进行了一些改进,因为后者分配了一个额外的对象

骆驼还有一个秒表,它使用java.util.Date来存储时间。 已对其进行优化以使用长值。

另一个改进是事件通知。 现在,我们会预先计算它是否正在使用中,并避免在与路由消息相关的事件中一起调用它们。 顺便说一句,在Camel 3.0中,事件通知程序已重构为使用Java 8 Supplier的API和许多精美的API,但所有这些都会造成大量开销。 在Camel 3.1中,我们已将通知程序恢复为Camel 2.x中的以前版本,并进行了其他优化。

因此,让我以说……结束这个博客。 太棒了 Camel 3.1使用更少的内存,不会调用太多的方法来执行得更快(请记住,我们可能不得不移动一些需要被调用的代码,但是以不同的方式执行此操作,以避免调用太多的方法)。

在涉及的源代码方面,最大的变化之一是从使用ServiceSupport(Camel中很多东西的基类)中的基于实例的记录器切换为使用静态记录器实例。 这意味着将创建更少的Logger对象,这也是更好的做法。

更好的性能

其他改进是,我们将骆驼作为交换属性保留的某些内部状态直接移到了Exchange的字段中。 这样可以避免在属性映射中存储键/值,但是我们可以使用诸如boolean,int等原语。由于通过getter获取布尔值要比通过键在Map中查找值更快,因此这样做的性能也更好。

实际上,在Camel 3.1中,然后在常规路由期间,Camel不会从交换属性中查找任何此类状态,这意味着没有方法调用。 仍然有一些状态存储为交换属性(将来可能会改进其中的一些属性,但是大多数这些状态仅很少使用)。 我们优化的是在路由过程中始终检查和使用的状态。

交换getProperty(5分钟采样)

骆驼2.25 572598 getPropety(字符串)

骆驼2.25 161502 getPropety(字符串,对象)

骆驼2.25 161502 getPropety(字符串,对象,类)

骆驼2.25 141962 getPropeties()

骆驼3.0 574944 getProperty(字符串)

Camel 3.0 167904 getPropety(字符串,对象)

骆驼3.0 167904 getPropety(字符串,对象,类)

骆驼3.0 91584 getPropeties()

骆驼3.1 0 getProperty(String)

骆驼3.1 0 getPropety(String,Object)

骆驼3.1 0 getPropety(String,Object,Class)

骆驼3.1 0 getPropeties()

如您所见,Camel 2.25和3.0查找了很多这种状态。 在Camel 3.1中,我们对此进行了极大的优化,并且根本没有查找-就像说状态以原始类型存储在Exchange上一样,JDK可以内联并真正快速地执行。

以下屏幕截图显示了骆驼2.25和3.1。 (3.1的屏幕截图与昨天相比略有过时,此后我们对Camel进行了优化)。 请参见下面的屏幕截图:

好的,还有许多其他较小的优化,在撰写此博客时,我目前正在研究一个优化。 好的,让我结束这个博客,并保存第3部分的详细信息。

翻译自: https://www.javacodegeeks.com/2020/02/apache-camel-3-1-more-camel-core-optimizations-coming-part-2.html

apache.camel

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

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

相关文章

Util包中Arrays

java.util 类 Arrays java.lang.Object -java.util.Arrayspublic class Arrays extends Object此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。 除非特别注明,否则如果指定数组引用为 …

Android的sqlite使用外部,Android 使用外部已经建立好的sqlite数据库

最近项目需要通过电话号码查询归属地,决定直接在本地sqlite的数据库进行查询,没必要去访问网络(虽然最后还是决定还是将数据库放在服务器上)一 首先先将外部的sqlite数据库放入assets文件夹下面注意:必须是sqlite数据库(XXX.db),如…

java流与文件——操作文件

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——操作文件 的相关知识; 0.2) for source code, please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/ch…

阅读副本和Spring Data第2部分:配置基础项目

在上一篇文章中,我们使用相同的数据设置了多个PostgreSQL实例。 下一步将是使用这两个服务器来配置spring项目。 如前所述,由于我们使用完全相同的数据库,因此我们将使用Spring Boot JPA帖子中的一些代码。 这将是我们的gradle构建文件 pl…

java生成UUID通用唯一识别码

一、UUID概述UUID含义是通用唯一识别码 (Universally Unique Identifier),这是一个软件建构的标准,也是被开源软件基金会 (Open Software Foundation, OSF) 的组织在分布式计算环境 (Distributed Computing Environment, DCE) 领域的一部份。 UUID 的目…

android 项目部署,Android发布项目到JCenter

JCenter是什么大家应该都用过各种各样的Github上的第三方开源组件。类似这种效果的compile wang.yuchao.demoforjcenterlibrary:DemoForJCenterLibraryModel:1.2.5我们会比较好奇Android Studio 是从哪里得到这个类库的?Android Studio是从build.gradle里面定义的Ma…

java流与文件——对象流和序列化

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——对象流和序列化 的相关知识; 0.2) for source code , please visit https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdva…

maven 版本号插件_测试Maven版本插件自动递增版本号

maven 版本号插件抽象 Maven版本插件是一个非常强大的工具,我在很大程度上依赖于它来协调软件版本。 通常,软件发行版本号遵循简单的1.0.0.0-SNAPSHOT格式。 但是最近我需要在版本号中添加一个限定符,例如1.0-beta-SNAPSHOT或1.0.0-fix-bug-d…

java中Date

在类 Date 所有可以接受或返回年、月、日期、小时、分钟和秒值的方法中,将使用下面的表示形式:年份 y 由整数 y - 1900 表示。月份由从 0 至 11 的整数表示;0 是一月、1 是二月等等;因此 11 是十二月。日期(一月中的某…

如何配置android的adb环境变量,如何配置adb环境变量?win7配置adb环境变量的方法...

本文教程小编分享就是win7系统配置adb环境变量的方法, windows7系统 电脑安装adb工具时,提示“adb不是内部或外部命令”这时候我们需要重新配置adb环境变量,那么win7系统怎么配置adb环境变量?网上介绍配置adb环境变量的方法比较少…

jep290涉及jdk版本_JDK 14 / JEP 305模式匹配“ Smart Casts”实例

jep290涉及jdk版本我通常将Java代码中instanceof运算符的存在视为“ 红色标志 ”,这意味着在某些情况下使用instanceof不一定是错误的,但是使用它有时表示可以通过更干净的方式解决设计问题,如所述本文结尾处引用的一些资源中的内容&#xff…

java中Date与DateFormat的格式输出

一、DateFormat java.text.DateFormat 使用 getDateInstance 来获取该国家/地区的标准日期格式。另外还提供了一些其他静态工厂方法。使用 getTimeInstance 可获取该国家/地区的时间格式。使用 getDateTimeInstance 可获取日期和时间格式。可以将不同选项传入这些工厂方法&…

二叉堆的操作总结(insert+deleteMin+increaseKey+decreaseKey+percolateDown+percolateUp)

【0】README 本文idea 均为原创, for source code, please visit https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter6/p140_binaryheap_conclusion 【1】insert操作 // Attention, the index of the heap starts from 1 void …

aws生态系统集成商_通过通用数据访问扩展AWS生态系统

aws生态系统集成商Amazon Web Services(AWS)可帮助组织托管和管理其数据流程,例如构建数据可视化和执行ETL任务。 在CData,我们可以轻松地将AWS Services与异构业务应用程序和分布式数据存储连接起来,以最终帮助企业对…

HTML.parser和正则解析,正则表达式+HTMLParser使用详.ppt

getText:/body getText: getText:/htmlgetText:除了前面3.2中输出的几个Tag,其余的Tag都在这里了。 3.4 XorFilter 把前面的AndFilter换成NotFilter测试代码: NodeFilter filterID new HasAttributeFilter( "id" );NodeFilter filterChild n…

FileDescriptor的作用

一、FileDescriptor 文件描述符类的实例用作与基础机器有关的某种结构的不透明句柄,该结构表示开放文件、开放套接字或者字节的另一个源或接收者。文件描述符的主要实际用途是创建一个包含该结构的 FileInputStream 或 FileOutputStream。 二、静态标准文件描述…

java流与文件——内存映射文件

【0】README 0.1) 本文描述转自 core java volume 2, 旨在理解 java流与文件——内存映射文件 的相关知识; 0.2)内存映射文件的目的是: 提高访问速度, 缓冲区Buffer; 0.3) 本文干…

java 函数式编程 示例_功能Java示例 第8部分–更多纯函数

java 函数式编程 示例这是第8部分,该系列的最后一部分称为“示例功能Java”。 我在本系列的每个部分中开发的示例是某种“提要处理程序”,用于处理文档。 在上一期文章中,我们已经使用Vavr库看到了一些模式匹配,并且还将故障也视…

html加css作品,我的影视作品,如何在博客园发布带有CSS样式的HTML

总结一下,我做过的视频:(顺便试试在博客园如何发HTML网页)发布网页总结:HTML可以正常发送,但最好将你要发布的html文件放在一个带有ID的div中,这样方便后期添加样式时通过ID添加,不会影响到网页中的其他布局…

FileInputStream

java.ioClass FileInputStream java.lang.Object java.io.InputStream java.io.FileInputStream 所有已实现的接口: Closeable public class FileInputStream extends InputStream FileInputStream 从文件系统中的某个文件中获得输入字节。哪些文件可用取决于主机环境。 Fil…