君子博学而日参省乎己 则知明而行无过矣

博客园 首页 新随笔 联系 订阅 管理

并行存储转发是一种高吞吐量策略,可以让消息消费者跟上消息流的速度。在并行存储和转发的过程中,可能会在消息未持久化到硬盘时,接收到了消息消费的确认信息,所以在这种情况下就不需要再持久化到硬盘了。值得注意得是,如果使用了jms事务,就不能使用并行储存转发。因为并行存储和转发是不保证消息的一致性的。 

Queue默认是使用并行存储转发的。当然也是可配置的。主要可配置项如下: 
concurrentStoreAndDispatchQueues 
concurrentStoreAndDispatchTopics 
concurrentStoreAndDispatchTransactions 

下面解析快慢两种消费者的情况下,并行存储转发的过程; 

慢消费者: 
 
1、producer发送一个消息M到destination 
2、broker发送消息M到持久层。持久层中是一些负责写入消息到日志中的线程。 
3、同时存储和转发。消息可能被转发给一个或者多个消费者。因为消费者较慢,在收到消息消费的确认信息之前,消息将被持久化到日志文件中。 
4、收到消息消费的确认信息。 
5、broker通知持久层删除日志文件中的消息。 
(KahaDB的可回滚日志中,所以消息不会被直接删除,而是会记录一条信息到日子,表示这条消息已消费完成。等到一个日志文件中所有的消息都被消费完成后,才会删除或者归档这个日志文件) 

快消费者: 
 
1、producer发送一个消息M到destination 
2、broker发送消息M到持久层。持久层中是一些负责写入消息到日志中的线程。 
3、同时进行存储和转发。 
4、消费者快速返回了消息消费完成的确认信息。 
5、但受到所有消费者返回的确认信息后,便会通知持久层删除该消息。此时前面准备去持久化的消息还被阻塞着,这个时候便不再需要写入到持久层中。直接从内存中删除。 

如果你要使KahaDB串行存储和转发,必须明确禁用并行存储转发。禁用Queue、topic、Transactions 

Xml代码  收藏代码
  1. <broker brokerName="broker" persistent="true" useShutdownHook="false">  
  2.   ...  
  3.   <persistenceAdapter>  
  4.     <kahaDB directory="activemq-data"  
  5.             journalMaxFileLength="32mb"  
  6.             concurrentStoreAndDispatchQueues="false"  
  7.             concurrentStoreAndDispatchTopics="false"  
  8.             concurrentStoreAndDispatchTransactions="false"  
  9.             />  
  10.   </persistenceAdapter>  
  11. </broker>  


下图展示串行存储和转发: 

 

1、producer发送一个消息M到broker上的某个destination 
2、broker发送消息到持久层。因为并行存储转发已关闭,消息将会被立即写入到日志文件中。 
3、消息被分发到一个或多个消费者 
4、消费者发送消息消费确认信息到broker 
5、当broker收到所有消费者的确认信息后,broker通知持久层删除该消息。 

为了避免丢失消息,JMS规范要求broker在发送给producer确认接收信息前把消息持久化。如果使用Jms事务中时,会将事务的相关信息也持久化。默认情况下,KahaDB并未如此配置。如果应用需要避免丢失信息,就需要对KahaDB的配置进行修改: 
1、配置并行存储转发为false,使用串行存储转发 
2、持久化时使用同步写入。配置enableJournalDiskSyncs为true。 

另外,使用事务可以提升持久层的效率。因为事务是批量处理消息的。在事务提交之前,所有的消息都不会写入到message store中的。这样就减少了IO,每次事务提交进行一次IO,而不是每条消息进行一次IO。

posted on 2013-07-04 18:54  刺猬的温驯  阅读(305)  评论(0)    收藏  举报