在学习Mule的过程中,发现MULE对于服务调用的性能做了不少优化工作,其中最显著的就是实现SEDA模型。
Staged Event Driven Architecture (SEDA) 是加州大学伯克利分校研究的一套优秀的高性能互联网服务器架构模型。其设计目标是:支持大规模并发处理、简化系统开发、支持处理监测、支持系统资源管理。它的核心思想是把一个请求处理过程分成几个Stage,不同资源消耗的Stage使用不同数量的线程来处理,Stage间使用事件驱动的异步通信模式。

可以参考
http://www.eecs.harvard.edu/~mdw/papers/seda-sosp01.pdf
http://larryzhu.bokee.com/6779982.html
http://www.ibm.com/developerworks/cn/java/j-jtp0730/
这几篇文章对SEDA和线程池相关知识有着详细的介绍,这里就不复述了。
了解了SEDA后可以看出,经过它的改造,一个请求的处理过程被分为了很多个stage,并且使用了事件驱动的异步通信。接收到请求的最初始的线程所做的事情仅仅是将请求转换为一个event然后放入一个Stage的事件队列中。每个Stage都有自己的线程池,来处理事件队列中的事件。与另一个 stage的通信也是通过在eventQueue中添加event的方式。
为什么要做此改造?
可以分析下面这个例子

前提假设:在一个单核系统中存在A、B、C、D四个组件,他们向外暴露服务。四个组件中A C D是进行普通业务处理,而B会涉及到调用WebService或大数据量查询等导致长阻塞的处理。现有两个请求R1和R2,R1需要的业务处理会调用A- C-D组件,R2的业务处理会调用C-B组件。假设R1请求过程中的CPU使用时间ST(Service Time)是2ms, 而几个简单的数据库访问导致的阻塞时间WT(Wait Time)是10ms。 R2请求过程中CPU使用时间ST是3ms,而调用WebService和大数据量查询导致的阻塞时间WT是150ms。
在传统线程池的方案中,对于具有N个处理器的系统,需要设置大约 N*(1+WT/ST) 个线程来保持处理器得到充分利用。理解起来很简单,就是需要在WT的阻塞时间内提供足够的线程来保持CPU一直进行ST的处理,达到最大的CPU利用率。
通过计算可以得到,R1需要的线程池大小是6,R2需要的线程池大小是51。若仅仅在接收请求时使用传统的线程池方案,R1、R2两种请求同时高并发时,线程池对他们一视同仁,假设线程池的大小是80,而并发数是1000,按照公平的假设,80大小的线程池平均的被分配给R1和R2两种请求,各拿 40。这样导致的结果就是,R1只需要6个线程却被分配了40个线程,浪费了资源,增加了额外的调度工作;R2需要51个线程却只分配了40个,会导致 40个线程全部阻塞时没有足够新线程处理其他的并发请求,CPU没有充分利用,请求处理速度下降,系统吞吐量下降。
这里的数字全部是假设,仅供分析。事实情况下的并发数和线程池都会大很多,但上面分析得出的结论同样适用。
不难看出解决上面问题的方法就是能够为不同的请求分配不同的线程数量。但是一个请求会交给多个组件进行处理,组件的调用关系和请求的数量种类都会不断变化,所以不可能静态的为每个请求配置线程池大小。但是组件却可以,系统中ABCD四个组件是可以确定的,他们的WT和ST也是可估的,可以为每个组件的服务设计线程池大小。若要为每个组件设计线程池,组件间的调用也需要由同一线程内的同步调用,改造为事件驱动的异步通信方式。
于是,SEDA的方案被设计出来了。上面的组件对应的就是SEDA中的一个个阶段stage。分阶段的事件驱动架构的原理也展现在眼前。
实际演练
在分析了SEDA的原理和作用后,我模拟了他最简单的功能,实现了一个简单的SEDA模型,并进行了一些实验和比较,亲身体验到了他对性能的优化。下面是实验过程:
首先,实现一个简单的SEDA模型以及测试器,见附件的 SedaTester.java和seda.properties,分别是模拟代码和相关参数的配置文件。为了方便,我将功能代码写在了同一个类中。
代码中有详细的注释,这里就不解释了,简单介绍一下它的结构和配置参数:

模拟器实现了两种并发处理,包括传统的线程池处理,对应图中NormalComponent部分,以及SEDA方案,对应图中SedaComponent部分。
此模拟器主要是为了测试性能上的优化,为了简化,没有设计组件之间事件驱动的异步通信,一个请求的处理过程只涉及到一个组件。不过它已经能体现出SEDA的优势——为不同的请求分配不同大小的线程池。
配置文件中,为两个请求对应的两个组件分别配置了ST和WT值,以及两个请求的并发数量,如果是使用SEDA,还要分别配置两个组件线程池的大小。 useSEDA这个boolean属性表示是否使用SEDA,不使用SEDA将使用普通的线程池进行处理,线程池的大小是两个SEDA组件线程池大小的和(sedaPoolSize1+sedaPoolSize2),这样能保证两种方案的线程总数一致。
下面是我个人的实验结果
ST1 |
WT1 |
ST2 |
WT2 |
sedaPoolSize1 |
sedaPoolSize2 |
count1 |
count2 |
结果 |
0.1 |
30 |
0.1 |
100 |
200 |
300 |
5000 |
5000 |
Seda:1875ms
Normal:1690ms
|
0.1 |
30 |
0.1 |
100 |
100 |
400 |
5000 |
5000 |
Seda:1594ms
Normal:1656ms
|
0.1 |
30 |
0.1 |
100 |
50 |
450 |
5000 |
5000 |
Seda:3172ms
Normal:1656ms
|
0.1 |
3 |
0.1 |
300 |
200 |
300 |
5000 |
5000 |
Seda:5343ms
Normal:3453ms
|
0.1 |
3 |
0.1 |
300 |
10 |
490 |
5000 |
5000 |
Seda:3375ms
Normal:3410ms
|
0.1 |
3 |
0.1 |
300 |
100 |
900 |
5000 |
5000 |
Seda: 1968ms
Normal:3482ms
|
0.1 |
3 |
0.1 |
300 |
38 |
962 |
5000 |
5000 |
Seda: 1890ms
Normal:3422ms
|
0.1 |
3 |
0.1 |
300 |
38 |
962 |
50000 |
50000 |
Seda: 16107ms
Normal:17085ms
|
0.01 |
3 |
0.01 |
300 |
38 |
962 |
50000 |
50000 |
Seda: 15450ms
Normal:23430ms
|
0.1 |
3 |
0.1 |
300 |
138 |
2962 |
30000 |
30000 |
Seda: 3895ms
Normal: 65664 ms
|
0.1 |
3 |
0.1 |
300 |
138 |
2962 |
300000 |
300000 |
Seda: 31574ms
Normal:76412ms
|
0.1 |
3 |
0.1 |
300 |
138 |
2962 |
300000 |
300000 |
Seda: 31761ms
Normal:94426ms
|
0.1 |
3 |
0.1 |
300 |
138 |
2962 |
300000 |
300000 |
Seda: 31561ms
Normal:???? ms
|
实验数据看似零乱,其实比较后不难发现,是按照两组件的WT比值、线程池大小比值的规律进行实验的。
结果分析:
1 在前几组数据中,SEDA的优势没有体现出来,原因可能是两个组件的WT相差不是很大,线程池和并发数量不大,不能体现出动态分配线程池的优化效果,相反会因为SEDA内部的线程管理和调度花费较多的时间,出现比传统线程池低效的结果。
2 在逐渐加大WT比值后,本来希望SEDA能体现优势,但是红色的数据显示了相反的情况,调整了线程池大小后发现红色数据中SEDA低效的原因是:两个组件线程池大小的比例不够大,只有200/300,而WT的比值是3/300,线程池大小的比值应该和WT的比值在某种程度成正比。当WT比值加大后,线程池的比值也需要加大调整。
3 逐渐好转后,到了橘黄色的数据已经比较明显的体现出了SEDA的优化,一方面是WT比值加大,两个线程池大小也调整到了较合适的比值,并且总的线程数量增大到1000,是原来的两倍,SEDA优化的效果开始体现。
4到了蓝色的数据,减少ST到0.01,并发增加到10万,SEDA比Normal缩短了8秒左右。
5 再下面的实验中,增加并发到了60万,线程池总数增加到3100,适当调整线程池比例后,SEDA已经能够缩短几十秒的时间。
特别是绿色标识的数据,优化的效果已经有点让我怀疑是不是我代码出了问题,是不是模拟器不能正确的测试出性能。这个也有待进一步确认。
6 最后一行数据之所以用四个问号来表示Normal的时间,是因为某几次实验过程中消耗的时间已经涨到200多秒而且还在不断继续上涨,不符合正常的预估。不知道是不是因为大并发和较大容量的时候,传统的线程池容易出现性能的异常。
总结一下,当不同请求的WT比值越悬殊、线程池大小越接近机器性能所允许的最大值、并发数量越满负荷、两个线程池大小的比值越合适时,就越能体现SEDA的优化效果。同时,必须根据某种算法,将两个组件的线程池大小调整到合适的比值(和WT的比值成正比),才能发挥SEDA的作用。否则,不合适的线程数目分配将严重折损SEDA的优化效果甚至产生反效果。
相关推荐
- **性能优化**:合理配置Actuator的监控点,及时调整系统性能,如内存、线程池等。 - **安全性考量**:除了基本的身份验证,还需考虑数据加密、API权限控制等安全措施。 - **测试策略**:充分运用Mock和自动化...
- **Apache MINA**:Openfire采用的网络通信框架,基于Java NIO,支持TCP/IP和UDP/IP等多种传输方式,提供高性能的网络通信服务。 #### 三、Apache MINA框架详解 - **统一API**:为不同类型的网络传输提供一致的...
内容概要:本文详细介绍了西门子S7-200SMART PLC与V20变频器通过Modbus RTU协议进行通信的具体方法和技术要点。首先阐述了硬件连接方式,强调了正确的接线和参数设置对于稳定通信的重要性。接着深入讲解了PLC程序的设计,包括Modbus主站初始化、启停控制、频率设定以及断电自恢复等功能模块的实现。此外还分享了一些实用的经验技巧,如避免通讯冲突、处理浮点数转换等问题。最后提到该方案已在实际生产环境中成功应用,表现出良好的稳定性和可靠性。 适合人群:从事自动化控制系统集成的技术人员,特别是熟悉西门子PLC和变频器产品的工程师。 使用场景及目标:适用于需要将旧型号PLC与变频器进行高效集成的企业,在不影响原有设备的基础上提升系统的智能化水平,减少人工干预,提高生产效率。 其他说明:文中提供了大量具体的编程实例和参数配置指南,有助于读者快速掌握相关技能并应用于实际工作中。同时提醒读者注意一些常见的错误及其解决方案,帮助规避潜在的风险。
内容概要:本文详细介绍了西门子PLC中用于电机控制的封装功能块,涵盖正转、反转、变频控制等多种功能。通过简化底层代码,提高编程效率和系统可靠性。文章展示了如何使用功能块实现正转、反转、变频控制、模拟量处理、故障处理等功能,并结合用户自定义数据类型(UDT)和多重背景技术,实现对大量电机的高效管理。此外,还提供了具体的代码示例,帮助读者更好地理解和应用这些功能块。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些需要频繁处理电机控制任务的人群。 使用场景及目标:适用于需要简化电机控制编程、提高系统可靠性和可维护性的工业环境。主要目标是减少重复编码的工作量,提升开发效率,确保系统稳定运行。 其他说明:文中提供的代码示例和方法不仅有助于初学者快速入门,也为有经验的工程师提供了优化现有系统的思路。通过使用这些功能块,可以在短时间内完成复杂电机控制系统的搭建和调试。
全球腐败感知数据(2000-2023)——3000行 33个指标 关于数据集 该数据集包含3000行和33列,涵盖了2000年至2023年的腐败感知指数(CPI)数据和各种治理指标。它包括国家排名、分数和其他指标,如公共部门腐败、司法腐败、贿赂指数、商业道德、民主指数、法治、政府效率、经济指标和人类发展指数。 这些数据可用于: 腐败趋势分析 腐败对GDP、人类发展指数和治理的影响 跨国比较 数据可视化和机器学习模型 该数据集对研究人员、数据分析师、政策制定者和对研究全球腐败趋势非常有用。
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
内容概要:本文档详细介绍了将贝叶斯优化应用于FBCCA(滤波器组公共空间模式)参数调整的完整解决方案,包括代码实现和优化流程。首先,通过MNE库加载并预处理EEG数据,进行7-30Hz的预滤波处理,提取相关事件片段。接着,定义了FBCABayesianOptimizer类,该类包含创建动态滤波器组、获取模型参数以及定义优化目标函数的方法。其中,参数空间由离散和连续参数组成,涵盖了滤波器数量、CSP组件数、起始频率、带宽、交叠率等,并通过Optuna库进行多维搜索。优化过程中采用5折交叉验证机制,同时引入智能早停策略以提高效率。最后,提供了优化结果的可视化工具,如优化轨迹图、参数重要性图和滤波器组配置图,帮助用户更好地理解和分析优化过程。 适合人群:具有一定编程基础,尤其是对机器学习、脑电数据分析及贝叶斯优化感兴趣的科研人员和技术开发者。 使用场景及目标:①通过动态滤波器组生成算法,捕捉频段间的过渡特征;②利用混合参数空间设计,探索不同参数组合的效果;③借助高效交叉验证机制和智能早停策略,提高优化效率;④通过可视化工具,直观展示优化过程和结果。 阅读建议:此资源不仅展示了完整的代码实现,还深入探讨了FBCCA参数调整的理论基础和实际应用。建议读者在学习过程中结合理论知识与代码实践,逐步理解每个步骤的原理,并尝试调整参数以观察不同设置对优化效果的影响。同时,可根据自身硬件条件,考虑扩展建议中的GPU加速、分布式优化和在线学习等高级特性。
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
街道级行政区划shp数据,wgs84坐标系,直接使用。
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
街道级行政区划shp数据,wgs84坐标系,直接下载使用。
Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
电子信息工程专业毕业论文模板_基于FPGA的CRC编码器设计.pdf
鄂尔多斯市-达拉特旗-街道行政区划_150621_Shp数据-wgs84坐标系.rar
内容概要:本文详细介绍了STM32与三菱PLC FX系列整合方案,涵盖多种功能模块的实现方法及其应用场景。首先,通过寄存器级别的低层操作展示了数码管驱动、模拟量采集、定时器PWM配置等功能的具体实现方式。其次,针对定位功能进行了深入探讨,包括12轴运动控制、4路200kHz高速脉冲输出以及CAN总线扩展等高级特性。此外,文中提供了三种不同层次的代码版本供开发者选择,分别是寄存器版本、库函数版本和即将发布的HAL库版本,满足不同程度用户的开发需求。最后,强调了该方案在工业控制领域的广泛应用前景,如包装机械、立体仓库等。 适合人群:具有一定嵌入式开发经验的研发人员,尤其是对STM32和三菱PLC有研究兴趣的技术爱好者。 使用场景及目标:适用于需要将STM32与三菱PLC进行深度整合的工程项目,旨在提高工业控制系统的灵活性和功能性。具体目标包括但不限于实现高效的梯形图上传下载、在线监控、多轴运动控制、模拟量采集及CAN总线通信等功能。 其他说明:文中不仅提供了详细的代码示例和技术细节,还分享了一些实用技巧,如寄存器操作注意事项、库函数的优势以及未来HAL库版本的发展方向。对于希望深入了解STM32与三菱PLC整合方案的读者而言,是一份不可多得的学习资料。
内容概要:本文详细介绍了西门子S7-200SMART PLC与V20变频器通过Modbus RTU进行通讯的具体实施方案,涵盖硬件接线、变频器参数设置、PLC程序编写以及触摸屏配置等方面的内容。重点解决了断电自恢复的问题,确保系统在断电重启后能够自动恢复正常运行。文中还提供了多个调试技巧和常见问题解决方案,如RS485接线注意事项、波特率设置、Modbus地址映射等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是熟悉PLC和变频器应用的专业人士。 使用场景及目标:适用于需要将PLC与变频器集成的应用场合,特别是在电力供应不稳定或存在突发断电风险的环境中。目标是提高系统的稳定性和可靠性,减少人工干预,提升生产效率。 其他说明:文中提到的实际案例表明,该方案已在多个工业现场成功应用并长期稳定运行,证明了其可行性和优越性。此外,作者还分享了一些个人经验教训,帮助读者避免常见的错误和陷阱。
内容概要:本文详细介绍了基于西门子200PLC的全自动不锈钢焊接系统的程序设计及其配套的维纶触摸屏程序。项目采用了模块化设计,分为多个功能块如故障处理(FB_FaultHandling)、复位(FB_Reset)、自动模式(FB_AutoMode)和手动模式(FB_ManualMode),每个功能块职责明确,便于维护和复用。此外,还包括详细的地址分配表、电路原理图以及触摸屏界面设计,确保了系统的通用性和可维护性。文中还特别强调了故障处理模块的堆栈设计、安全回路的双冗余设计以及焊接参数的自动化计算等功能,展示了工业控制领域的最佳实践。 适合人群:从事PLC编程、工业自动化控制、机械设备维护的技术人员和工程师。 使用场景及目标:适用于需要设计和实施全自动焊接系统的工程项目,旨在提高生产效率、减少故障停机时间、优化焊接质量。通过学习本文,读者可以掌握模块化编程技巧、故障处理方法以及人机交互界面设计的最佳实践。 其他说明:本文不仅提供了具体的代码实现和电路图,还分享了许多实际调试经验和优化建议,帮助读者更好地理解和应用这些技术和方法。
街道级行政区划shp矢量数据,wgs84坐标系,下载直接使用
街道级行政区划shp数据,wgs84坐标系,直接下载使用。