activiti异步执行_对基于消息队列的Activiti异步执行器进行基准测试

activiti异步执行

一点历史

永无休止的一件事是,Activiti在某些非常大的规模的大型组织中的使用方式。 过去,这导致了各种优化和重构,其中包括异步执行器-替换旧的作业执行器。 对于未启动的用户:这些执行器在流程实例中处理计时器和异步继续。 特别是在过去的两年中,我们已经看到它的使用大大增加。 异步执行器的引入极大地提高了性能。 但是,去年在巴黎举行的社区活动中,我们了解到,在处理大量工作时,执行者使用的查询可能会导致需要进行表扫描。 这永远不是一件好事。

因此,我们知道在完成版本6之前,我们确实想做一件事,那就是重构异步执行器,使它使用的所有查询都变得非常简单。 这确实意味着我们必须将作业数据拆分为与不同类型和状态匹配的各种表,同时仍要使API与以前的Activiti版本兼容。

在过去的几个月中,我们一直在做这些事情(包括许多其他事情),并取得了一些不错的结果以及一些新的不错的API,这些API丰富了该平台。 我可以在“新的”异步执行程序的工作方式上写另一个博客,但是昨天我已经完成了文档工作,因此,如果您对所有工作方式都感兴趣, 请查看在线文档或检查工具 栏上 的源代码。 v6分支 。

架构设计当然受我们从过去两种实现中学到的知识的影响,但同时也受消息队列系统中概念的影响很大。 设计目标之一是插入消息队列并运行它应该非常容易,因为我们有一种直觉,认为这将对性能有所帮助。

因此,我们做到了。 由于新的体系结构,使异步执行程序与消息队列一起工作几乎是微不足道的。 如果您对实现感兴趣, 我还会在文档中添加有关此主题的部分。

而且,当然,您知道我,我只是想将这两个执行程序实现相互比较基准��

基准项目

您可以找到我在Github上使用的代码: https : //github.com/jbarrez/queue-based-async-executor-benchmark

基本上,它的操作是使用配置属性文件运行Main.java。

  • 使用适当的配置启动流程引擎(我最近在网上看到一些Activiti基准测试,这些基准在不使用适当的连接池数据源的情况下对Activiti的性能进行了基准测试。
  • 如果以“生产者”身份运行,将启动10000个流程实例,每10毫秒一个。 定期的统计信息将被打印到控制台上。
  • 如果以“执行程序”身份运行,则将流程引擎配置为启用异步执行程序。
  • 可以有任意数量的生产者/执行者,但是所有生产者/执行者都进入同一个数据库。

项目中使用的流程定义如下:

截图-2016-07-20-00.37.54-904x412

需要注意的重要一点(在图中不可见)是,在此重要的流程定义中,所有服务任务都是异步的。 并行派生之后的服务任务与加入的并行网关一样配置为互斥的 。 这里有两个计时器,其中用户任务上的一个是1秒,子流程上的一个是50分钟。 总而言之,当启动流程实例时,它导致需要执行27个作业才能到达终点。 对于10000个实例,这意味着我们正在有效测试270 000个作业的吞吐量。

请注意,与任何基准测试一样,原始数据说明了一切,但不是全部。 这一切都取决于服务器硬件,实际的流程定义和许多其他细节。 但是,如果在完全相同的硬件上执行完全相同的代码,相对数字会给我们带来很多启发。 阅读下一部分时,请记住这一点。

测试环境

所有基准测试都是在Amazon Web Services(AWS)上运行的,生产者/执行者使用EC2服务器,r3.4xlarge(16个vCPU,16个vCPU)上的数据库使用RDS PostgresQL (因为Postgres是一个很棒的数据库,非常容易设置) 122 GiB内存)。

使用以下EC2配置

  • RDS(postgres):r3.4xlarge(16个vCPU,122 GiB内存)
  • 生产者引擎:c3.4xlarge(16个vCPU,30 GiB内存)
  • 执行器引擎:c3.8xlarge(32个vCPU,60 GiB内存)

所有服务器都在欧盟西部地区运行。 因此,所有测试结果都具有真实的网络延迟(没有运行在localhost基准测试上的延迟,因此跳过了网上经常看到的联网)。 当运行上面的项目时,JVM分配了8GB的空间。

我们将使用的指标是作业的吞吐量 ,以作业/秒表示。 简而言之,在测试运行之后,我们验证数据库中的数据是否正确(即10K完成的流程实例),并采用第一个开始时间和最后一个结束时间,这使我们获得了x秒的时间。 则吞吐量为x / 270000(众所周知,每个流程实例等于27个作业)。

基线测量

基准测试的第一件事是“基准”,即由线程池支持的常规异步执行程序(即v5中异步执行程序的改进设计)。 在此测试中,我们使用了2台服务器,并进行了以下配置(注意:6.0.0.Beta3实际上是快照版本):

一个 C d
Activiti版本 6.0.0.Beta3 6.0.0.Beta3 6.0.0.Beta3 5.21.0
生产者引擎 1个 1个 1个 1个
执行器引擎 1个 1个 2 2
#池中的线程 32 10 10 10
阻塞队列大小 256 100 100 100

图片4

一些有趣的观察:

我认为配置A会比配置B更好,因为这台机器毕竟有32个CPU,因此将线程池的线程数与此匹配是合理的。 但是,配置B的设置非常相似,除了只有10个线程和较小的阻塞队列之外,它的性能大大提高(310 vs 210作业/秒)。 一个可能的解释可能是32个线程争用太多? 我确实记得当初选择默认值“ 10”时,我们进行了一些基准测试,其中10是吞吐量最佳的“魔术数字”(但我认为这取决于所使用的机器。)

我希望添加另一个执行程序节点会产生更大的影响,毕竟我们要添加32个CPU的计算机,但是收益很小(310到326)。 我们将学习原因,并在本文的稍后阶段进行修复。

使用Activiti版本5.21.0的配置D使用与配置C相同的设置。但是,改进的版本6的异步执行程序显然在这里胜出(326 vs 266)。 这当然是我们希望的:-)。

到目前为止,我们最好的结果是每秒326个作业 (并使用两台服务器)。

基准线的变化

鉴于以上设置,可以询问运行混合的生产者/执行者时产生的影响。 这是Activiti引擎默认的运行方式:引擎将同时负责启动流程实例并立即执行它们。 这是配置E (与配置C相同,除了两个引擎现在都是生产者/执行者),结果如下所示。 而且显然性能较差。 一种解释可能是该机器已经每10毫秒使用10个线程来启动流程实例,这可能导致与异步执行器的10个线程相当多的争用。 可能可以对该设置进行很多调整以获得更好的数字,但这不是此博客的目标。 但是结果仍然很有趣。

图片3

因此,考虑到两个执行器引擎胜于一个执行器引擎,合乎逻辑的事情是尝试三个执行器。 这是配置F。

类似于从一个执行程序到两个执行程序,吞吐量提高了。 但不是以一种壮观的线性方式。

图片2

介绍基于消息队列的异步执行器

现在该切换到基于消息队列的异步执行器了,现在我们有了基准编号。 我选择了最新版本的ActiveMQ ,因为我对此很熟悉,并且设置起来非常容易。 我没有花时间调整ActiveMQ,切换持久性策略或尝试替代方法。 因此,那里也可能会有一些利润。

在基准项目中,我将Spring与以下配置一起使用: https : //github.com/jbarrez/queue-based-async-executor-benchmark/blob/master/src/main/java/org/activiti/MyConfigMessageExecutor.java 。 之所以选择Spring,是因为MessageListenerContainer提供了一种简单的方法来使消息队列侦听器可以很好地与多个线程一起工作(JBoss这样的应用程序服务器可以为您提供其他功能)。 更具体地说,MessageListenerContainer的concurrenConsumers设置允许设置用于以智能方式监听消息的线程数。 是的,此类确实具有许多可能会更好地影响结果的属性,但这又不是重点。 请记住相对数字。

对于此配置,我们使用与config C类似的设置(到目前为止,我们在两台服务器上的最佳结果),称为config G:1个生产者引擎,2个执行者引擎。 请注意,我们现在还在混合中添加了“队列服务器”,它使用的是c3.8xlarge机器(32个vCPU,60 GiB RAM),类似于执行引擎服务器。

结果在下面…简直太棒了:在等效设置(但带有额外的消息队列服务器)中的消息队列异步执行程序比基于线程池的异步执行程序快四倍

图片5

一个小的实现说明:我们不得不切换到UUID ID生成器 ,因为吞吐量对于默认值而言太高了。 请记住,UUID生成器比默认生成器慢,结果甚至更棒(因为我们在这里实际上谈论的是毫秒)。

有趣的观察!

如果您运行基准测试项目,则会看到它会定期吐出一些统计信息,以便您可以跟踪系统中有多少作业,计时器,用户任务,历史活动实例,流程实例等。

在运行消息队列设置时,从这些数字中可以很清楚地看出一种模式。 基于线程池的异步执行器可以更快地完成流程实例(例如,大约1分钟后,我们看到一批流程实例已完成),而对于基于消息的异步执行器,流程实例实际上都是在最后一次大爆发中完成的。 这表明后者将更多地分散流程实例活动的执行,而基于线程的活动将继续进行直到完成为止。

团队中的一些讨论导致了对此的解释:基于线程池的线程将始终将下一个异步作业传递给执行器,而基于消息的线程则将其放在队列中,那里已经有数千条消息在等待。 现在添加一个事实,我们对流程实例有很多排它异步作业,这意味着对于基于线程池的异步作业,许多线程试图获取流程实例锁,但是由于执行了排他异步操作而失败。 但是,这项工作没有获得 ,很快就重新开始了。 对于基于消息队列的消息队列,将它们再次添加到消息队列的末尾。 其中有数千条其他消息正在等待。 回到执行此特定消息时,排他锁很可能已经很久了。

这导致在基于线程池的异步执行程序中进行一些重构:删除并重新插入作业,而不是简单地释放作业的锁定,从而有效地模拟了队列行为。 这是修复程序: https : //github.com/Activiti/Activiti/commit/d08a247570336c872bb17ce513c1fb95b3ba47a2#diff-bd9c7efdb4c57462f6fe71641b280942R212 。

在与config C完全相同的设置(称为config H(1个生产者,2个执行者))中对这些基准进行基准测试,这表明我们此简单的解决方案将吞吐量提高了34%! 现在我们有了一个新的基准

图片6

更好的消息队列异步执行器结果

因此,在消息队列结果(配置G)中,我们使用了10个线程的相当保守的设置来侦听消息。 想法是我们还有10个线程池用于线程池。 当然,消息队列使用者从根本上不同于轮询线程:此类使用者与队列具有持久连接,而队列代理实际上将工作推给其使用者。 这应该更有效。 因此,我们尝试了以下配置,在这些配置中,我们改变了使用者(从而消耗了线程)和执行程序节点的数量。

一世 Ĵ ķ 大号
生产者引擎 1个 1个 1个 1个
执行器引擎 2 2 3 3
#消费者/引擎 32 64 32 64

图片9

因此,一个不错的观察结果是,添加更多的消费者是超级有效的。 我们正在达到2222.9作业/秒吞吐量 。 如果您问我,那是极快的速度,是基于线程池的异步执行器的五倍。

可悲的是,将更多的执行器机器添加到组合中实际上对性能不利。 我认为瓶颈现在已成为数据库,以及它如何处理大规模进行的所有并发。 当然,我根本不调整数据库 ,而只是常规RDS postgres实例。 或尝试使用Aurora或Oracle(在我以前的基准测试中获得最好的结果)。 但是,这里的重点是相对数量 ,而不是挤出吞吐量的最后一部分。 我认为相对数字点已经确定为��

结论

数字说明了一切:基于新消息队列的异步执行器击败了基于线程池的异步执行器。 这是否意味着您必须立即切换? 不, 常规的异步执行器也非常快(每秒436作业仍然很快),但是更重要的是,设置非常简单,因为Activiti引擎可以处理所有事情。 在项目中添加消息队列意味着更多的复杂性:可能会失败或崩溃的另一件事,额外的监视,维护等。但是,当您执行大量 (我的意思是“很多”)异步工作时,您会重新达到默认异步执行器可以执行的操作的限制,很高兴知道还有替代方法。

我们还要忘记这里得出的另一个结论:版本6中的新异步执行程序实现是对版本5的重大改进!

进一步的工作

当前的实现仅是Spring / JMS。 但是,该实现很容易移植到其他系统和/或协议(应用程序服务器,STOMP,AMPQ,AWS SQS等)。 对于将成为流行的下一个选择的反馈,我们深表感谢。

有趣的是,这种基于消息队列的异步执行器使实现“优先级队列”非常简单。 优先级队列是我们许多大型用户所要求的功能:提供特定的流程定义/实例/在特定条件下/ ...优先级与常规作业相比。 容易想象如何设置多个队列和/或分配更少或更多的使用者以赋予某些用例优先级。

翻译自: https://www.javacodegeeks.com/2016/07/benchmarking-message-queue-based-activiti-async-executor.html

activiti异步执行

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

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

相关文章

chrome浏览器设置网页快速到顶部和到底部的方法

鼠标移到浏览器的书签任意位置,点击鼠标右键添加书签,在添加书签的窗口输入名称和js代码,然后把书签移到浏览器书签栏的最左侧,这样每次浏览网页就可以使用快捷方式快速到底部或者顶部了。 快速到顶部的js代码:javascr…

apache pdfbox_Apache PDFBox命令行工具:无需Java编码

apache pdfbox在博客文章Apache PDFBox 2中 ,我演示了将Apache PDFBox 2用作从Java代码中调用的库来操作PDF。 事实证明,Apache PDFBox 2还提供了可以直接从命令行直接使用的命令行工具 ,而无需其他Java编码。 有几种命令行工具可用&#xff…

【WebRTC---源码篇】(六)NACK判断包位置的关键算法

首先保证a与b不相等 template <typename T, T M = 0> inline bool AheadOf(T a, T b) {static_assert(std::is_unsigned<T>::value,"Type must be an unsigned integer.");return a != b && AheadOrAt<T, M>(a, b); } template <type…

spring集成mq_使用Spring Integration Java DSL与Rabbit MQ集成

spring集成mq我最近参加了在拉斯维加斯举行的2016年Spring大会 &#xff0c;很幸运地看到了我在软件世界中长期敬佩的一些人。 我亲自遇到了其中的两个人&#xff0c;他们实际上合并了几年前我与Spring Integration相关的一些次要贡献– Gary Russel和Artem Bilan &#xff0c;…

MyEclipse 如何使用断点调试

文章目录1、在需要的代码行处打断点右键添加断点双击添加断点快捷键添加断点2、以debug模式开启服务器通过debug执行列表&#xff0c;选择服务器启动当前程序按右键&#xff0c;选择debug as&#xff0c;再选择服务器启动开发视图底部server列表选择服务器开启debug视图&#x…

【WebRTC---源码篇】(八)音频数据采集

ADM的创建 1.Audio Device Module是在逻辑层与硬件设备层之间进行了转换,需要使用什么功能,调用什么接口就可以,不要管底层平台实现。 2.AudioDeviceModule是一个接口类,定义了一系列接口。最终实现由子类AudioDeviceModuleForTest实现,其中包括一些测试函数(对设备的…

jsf netbeans_NetBeans Java EE技巧9:从数据库创建JSF应用程序

jsf netbeans您需要非常快速地创建数据库前端吗&#xff1f; NetBeans IDE允许人们以很少的代码就为一组数据库表开发JSF应用程序前端。 现在&#xff0c;本教程是一个老歌&#xff0c;但是一个好东西……对于那些不了解它的人来说&#xff0c;值得再次提及。 首先&#xff0c…

cloud foundry_介绍“又一个” Cloud Foundry Gradle插件

cloud foundry在与两个同事&#xff08;感谢Mark Alston和Dave Malone &#xff01;&#xff09;一起使用自动Jenkins管道部署Cloud Foundry应用程序的过程中&#xff0c;我决定尝试编写Gradle插件来执行一些通常需要完成的任务使用命令行Cloud Foundry Client完成 。 引入一个…

Oracle/MySQL/Java数据类型对应表

文章目录数据类型对照表MySQL 的 int、bigint、mediumint、smallint、tinyint 的对比关于 MySQL 整型显示位数的问题关于 MySQL 的 timestamp关于 JDBC 类型数据类型对照表 MysqlOracleJavaBIGINTNUMBER(19,0)java.lang.LongBITRAWbyte[]BLOBBLOB RAWbyte[]CHARCHARjava.lang.…

java10个基础错误_我们处理了10亿个Java记录的错误-这是导致97%的错误的原因

java10个基础错误97&#xff05;的记录错误是由10个唯一错误引起的 在2016年&#xff0c;一件事在30年内没有改变。 开发和运营团队仍依靠日志文件对应用程序问题进行故障排除。 由于某些未知原因&#xff0c;我们隐式信任日志文件&#xff0c;因为我们认为事实隐藏在其中。 如…

3制造数据集_基于MBD的产品设计制造技术研究

本篇节选自论文《基于MBD的产品设计制造技术研究》&#xff0c;发表于《中国电子科学研究院学报》第8卷第6期&#xff0c;作者为中国电子科技集团公司第14研究所专家朱建军。本文经授权转载自公众号学术plus&#xff0c;版权归原作者所有。作者&#xff1a;中国电子科技集团公司…

【WebRTC---源码篇】(九)媒体协商

1.媒体协商的过程 2. 重要的接口类 3.时序图 4.几个关键点 5.code if (InitializePeerConnection()) {peer_id_ = peer_id;//参数1:观察者,创建成功后回调OnSuccess//参数2:消息类型,自动推导peer_connection_->CreateOffer(this, webrtc::PeerConnectionInterface::RTCOff…

【WebRTC---源码篇】(七)NACK的处理流程

NACK调用栈 从分发器接收Packet包 void RtpVideoStreamReceiver::ReceivePacket(const RtpPacketReceived& packet) {if (packet.payload_size() == 0) {// Padding or keep-alive packet.// TODO(nisse): Could drop empty packets earlier, but need to figure out how…

java实现资源监视器_实现Java监视的12个步骤程序存在缺陷

java实现资源监视器Java监视的当前状态最大的问题是什么&#xff1f; 生产中的错误很像喝醉的短信。 您只有在事情已经发生之后才意识到出了点问题。 发短信日志通常比应用程序错误日志更有趣&#xff0c;但是……两者可能同样难以修复。 在本文中&#xff0c;我们将执行一个…

hystrix应用 博客_使用Hystrix DSL创建弹性骆驼应用程序

hystrix应用 博客Apache Camel是一个成熟的集成库&#xff08;到现在已有9年的历史了&#xff09;&#xff0c;它实现了Enterprise Integration Patterns一书中的所有模式。 但是Camel不仅是EIP实现库&#xff0c;它还是一个不断发展&#xff0c;添加新模式并适应行业变化的现代…

notebook打开外部文件_CAD外部参照真是个好东西!

好课推荐&#xff1a;零基础CAD&#xff1a;点我CAD室内&#xff1a;点我 周站长CAD&#xff1a;点我CAD机械&#xff1a;点我 Bim教程&#xff1a;点我CAD建筑&#xff1a;点我CAD三维&#xff1a;点我全屋定制&#xff1a;点我 ps教程&#xff1a;点我苹果版CAD:点我 3dmax教…

JSP动作元素/活动元素

文章目录jsp:forwardjsp:includejsp:paramjsp:useBeanjsp:setPropertyjsp:setProperty name"" property"" value""jsp:setProperty name"" property"" param""jsp:setProperty name"" property"*&…

gradle groovy_适用于Java开发人员的Groovy吗? 认识Gradle,Grails和Spock

gradle groovyJava开发人员最感兴趣的Groovy用例有哪些&#xff1f; 尽管已经有一段时间了&#xff0c;但似乎只有Groovy最近才开始使用Groove。 对于某些人来说&#xff0c;它基本上只是另一种深奥的JVM语言&#xff0c;但是由于一些流行的工具可以帮助您使用Java&#xff0c…

JSP 指令元素

文章目录page 指令import 属性pageEncoding 属性contentType 属性session 属性isELIgnored 属性errorPage 属性isErrorPage 属性include 指令file 属性taglib 指令uri 属性prefix 属性jsp 源文件转换成对应的 .java 文件时&#xff0c;jsp 的指令会影响 Java 源代码的生成&…

indesign中调出字符样式快捷键_Word中十大黄金快捷键,你会用几个?

在使用Word文档时&#xff0c;熟练使用快捷键能够有效的提升我们的工作效率&#xff0c;但是&#xff0c;Word中快捷键也比较多&#xff0c;要想全部掌握&#xff0c;那不太现实&#xff0c;这里&#xff0c;易老师给大家挑选了10组黄金快捷键&#xff0c;非常实用。01 快速移动…