有效的JMS处理

cha*_*ged 12 database transactions jms

我们有一个JMS队列,它接收大量的消息.

监听器必须使用数据库事务在数据库中保存消息,然后提交JMS事务.

那么我怎么能更有效地做到这一点,我不必在每条消息上做数据库和JMS提交.

Bri*_*ach 10

不要在每条消息上执行此操作,请分批执行.JMS像数据库一样支持事务; 启动JMS事务,读取N条消息.启动数据库事务,插入N条消息.提交到JMS,提交到DB.

这显然会引发竞赛发生的窗口(两次提交之间发生崩溃).你现在拥有它,但仅限于一条消息.如果你想解决这个问题,你要么面对XA事务(两阶段提交),要么至少看一些重复检测方案.有关介绍,请查看:http://activemq.apache.org/should-i-use-xa.html

  • 我不会使用MessageListener接口,只会在收到消息时执行操作.您可以这样做(跟踪您通过成员变量收到的消息数量,启动和提交事务等),但是您正在扩展竞争条件窗口,因为您依赖于消息来触发任何操作.这真的不是最好的方法.你做一个传统的循环,你从队列中读取消息(阻止调用超时或非阻塞),并在你有N个消息或Y时间过去时进行提交,你会好得多. (3认同)

T.R*_*Rob 8

异步消息传递背后的前提,特别是在使用MDB时,每条消息都是原子的.也就是说,处理任何一条消息的结果应该与处理任何其他消息的结果无关.解决问题的理想方法是保留消息的原子性.

如果您要在同一工作单元中处理多个消息,那么您将失去这种原子性.例如,假设您决定每25封邮件同步一次.如果第25条消息有错误,例如阻止从队列中检索它的代码页转换问题,则将退回整批消息.然后他们都将被重新传递.消息的重新传递计数将随着每个读取/回退周期而增加.一旦重新传递计数超过了您的应用服务器中设置的阈值,所有25条消息将被丢弃或重新排队,具体取决于您的配置.批处理越大,在错误情况下可能会影响的消息越多,因为整个批处理生命或死在一起.将批量大小设置为100,如果发出单个有毒消息,则100条消息将面临风险.

另一种解决方案是允许MDB中的许多处理线程.使用JMS,您可以在同一连接下生成许多会话.每个会话都可以管理自己的工作单元,因此每个会话可以独立启动XA事务,获取消息,更新数据库然后提交事务.如果一条消息不正确,则只会影响该消息和数据库更新.

这有例外.例如,如果处理大批量并且消息都来自同一生产者,则通常使用除MDB之外的其他内容来获取许多消息并在同一工作单元下更新许多行.类似地,如果消息是序列相关的,那么并行处理是不可能的,因为它不会保留序列.但话说依赖序列的消息不是原子的.同样,在这种情况下,MDB不是理想的解决方案.

根据您的传输提供程序,支持的线程数可能仅受内存存储的限制.例如,WebSphere MQ可以轻松处理队列中数百个同时的getter线程.检查应用服务器的MDB配置的调整,以查看可以启动的线程数,然后验证传输是否可以处理负载.然后玩一下,找到最佳线程数.随着线程从一个增加,但只有一个点,性能将急剧增加.过去,您通常会看到一个平台,然后随着线程管理开销抵消性能提升而下降.swe3et点所在的位置取决于消息传递代理的加载程度以及它是否受CPU,内存,磁盘或网络的限制.