使用Seda架构时总会利用队列传递消息。在java应用中需要注意使用seda队列对内存的使用模式,否则可能会因为jvm garbage的原因降低系统的处理能力。
在讨论seda队列的机制之前,需要了解一下Sun jvm garbage的的设计原则:
1)大部分对象总是会在新生代被分配以及释放。
2)旧生代对象引用新生代对象的情况很少出现。
如果违背以上原则,将可能诱发频繁的Full GC导致应用的处理能力急剧下降。严重的情况下会导致秒级频率的Full GC。
下面我们看一下Seda机制下的队列的问题。
1:原始问题:队列囤积的大量消息,那么将违背原则1),并诱发不必要的Full GC。
Seda的设计常常导致应用分成不同的片段,不同的片段之间使用队列传递消息衔接。这样一旦某个片段的执行速度相对较慢,则可能会导致队列囤积大量的消息。如果没有对队列的实现进行优化,则会违背garbage设计原则1。从而导致大量full gc出现——因为此时队列囤积的消息往往会被转移到旧生代,那么将会出现频繁的释放旧生代内对象的情况。此时诱发高频率的full gc。
解决这一问题的思路:
1)减少队列中消息的存储空间,并适当增加jvm新生代的内存比例,以避免队列的消息被转移到旧生代。
2)让队列的存储空间固定下来,不随着消息的个数变化而变化。
思路1的应对方法:
1)减少队列大小:此方法虽然简单,但较难实践。因为很难在系统的容错性以及队列的内存性能上进行平衡。从系统容错的角度,我们常常希望队列足够大,并且能够应对一定程度的峰值。
2)减少队列中消息对象的大小
一个消息对象中最大的内存开销往往是消息的数据内容,因此我们可以考虑使用单独的机制存储所有消息的数据内容,以避免队列占用过大的开销。在适当提高jvm 新生代比例的情况下,可以有较高的几率让队列消息仍然保持在新生代内。
方法:最简单的方法是使用文件系统存储。或者可以使用单独维护的一片内存空间,该空间的内存大小相对固定,使用这个空间来分配每个消息内容所需要的存储。再次也可以考虑使用sun jvm的提供direct memory技术。
Mule的社区版本的队列使用了上述机制。
思路2的应对方法
内存队列初始创建时,就将消息对象的空间全部分配。添加消息到队列时,实际上是将消息的内容复制到队列中某个闲置的空消息。从队列取消息时,实际上是将队列内部的消息对象复制一份同样内容的消息并返回给接收者(或者直接引用)。
这样有以下2点优势:1)队列以及预分配的消息被最终被交换到旧生代后,将不再占用对新生代的内存。2)旧生代内的队列以及预分配消息不会被释放,从而满足了garbage的设计原则1。达到较好的gc效果。
注意事项:如果消息对象内部嵌套引用其他对象,务必要保证内部引用所有对象都按照预分配内存原则进行。否则将违背垃圾回收的设计原则2. 如果内部的对象使用了jdk的类型,无法满足此原则时,此时必须要使用其他的方法来回避直接使用此类对象
譬如String。如果我们的消息对象使用了String属性,那么将无法满足该要求:无法为队列内部的预分配消息对象的String属性预留一定的内存空间,并且当Put Message进入队列时,将要put的消息的String属性的内容拷贝给预分配了空间的消息的String属性。
而且我们也不能简单的把所要put消息的String对象简单的赋值给队列内部的Message对象对应的String成员。因为这将违背Garbage的设计原则2————旧生代对象(队列内的预分配消息对象)引用了在新生代上分配的String对象(被put的消息的String对象)。此时也会诱发不必要的Full GC。通常建议使用其他方法绕开对此类对象的使用,譬如使用char数组来代替String。通过简单的封装(getXXX),我们仍然可以让应用使用String类型的属性,而不是直接使用复杂的char数组数据结构。
LMAX的队列机制使用了这一方法,但使用时务必需要确保Message对象内部所有成员都能够预分配内存。
分享到:
相关推荐
NULL 博文链接:https://xylong.iteye.com/blog/1441956
基于SEDA架构的网格服务容器设计与实现.pdf
基于SEDA的企业服务总线的设计与设计,清晰地讲解了SEDA的结构与设计原理,为高并发网络响应提供了一种实现思路
we call the staged event-driven architecture (SEDA). SEDA is intended to support massive concurrency demands and simplify the construc- tion of well-conditioned services. In SEDA, applications consist...
Staged Event Driven Architecture (SEDA) 是加州大学伯克利分校研究的一套优秀的高性能互联网服务器架构模型
采用分级事件驱动架构SEDA(Staged Event Driven Architecture),通过划分阶段Stage的方式解除耦合,在阶段之间采用事件进行异步消息通信,结合非阻塞的I/O机制设计实现了一个事件驱动的网格服务容器,并从吞吐量、...
NULL 博文链接:https://ailikes.iteye.com/blog/2233024
阶段事件驱动架构设计论文,详细介绍了seda的架构体系。
基于SEDA的企业服务总线的设计与实现,基于SEDA的企业服务总线的设计与实现
【大纲】 服务端软件=排队服务 回顾常见的并发模型 介绍SEDA 分享我们的经验
SEDA(StagedEvent-DrivenArchitectrue)--兼谈服务器体系结构设计一.引言
seda过载保护
Staged Event Driven Architecture (SEDA) 是加州大学伯克利分校研究的一套优秀的高性能互联网服务器架构模型
1、安装环境 2、安装依赖软件 3、安装配置Seda 4、测试seda能否正常工作
mule & seda 学习二.docx
有关 ehensin-seda 的最新信息,请访问我们的网站:
SEDA: An Architecture for Scalable,Well-Conditioned Internet ServicesMatt Welsh, David Culler, and Eric BrewerUC Berkeley Computer Science Division mdw@cs.berkeley.eduhttp://www.cs.berkeley.edu/~mdw/...
此外,该框架支持与Spring集成,提供使用annotation的方式让开发人员方便地注册事件及定义事件处理,使用Spring事务管理器管理事务时,支持Unit Of Work模式存储数据。 2 核心概念 2.1 Aggregate Aggregate(聚合)...
唤醒Wake是一个事件驱动的框架,基于SEDA,Click,Akka和Rx的思想。 从某种意义上说,它是通用的,旨在支持计算密集型应用程序以及高性能网络,存储和旧版I / O系统。 我们实现了Wake以支持高性能,可扩展的分析处理...
在本文中,我们对各种垃圾邮件过滤器进行了全面调查,例如朴素贝叶斯分类器,基于SEDA算法的改进贝叶斯过滤器,自适应过滤器和模糊过滤器。 我们针对已获取的数据集的各种性能评估指标研究了它们的性能。 分类精度...