ActiveMQ学习笔记(16)----Message Dispatch高级特性(二)

1. Optimized Acknowledgetment

  ActiveMQ缺省支持批量确认消息,由于批量确认会提高性能,如果希望在应用程序中禁止经过优化的确认方式,可以采用以下几种方式:

  1. 在Connection的URI上启用Optimized Acknowledgements

ActiveMQConnectionFactory  factory = new  ActiveMQConnectionFactory("tcp://localhost:61616?jms.optimizedAcknowledge=true");

  2. 在ActiveMQConnectionFacrory上启用Optimized Acknowledgements

   factory.setOptimizedAcknowledge(true);

  3. 在Connection上启用Optimized Acknowledgements

  ActiveMQConnection.setOptimizedAcknowledge();

  4. 在5.6 以后的版本,还可以在Connection URI上设置setOptimizedAcknowledgeTimeOut参数,默认值为300ms,你还可以设置自己要用的值,0表示禁用。

2. Producer Flow Control(生产者流量控制)

  流量控制的含义:当生产者产生消息过快,超过流量限制的时候,生产者将会被阻塞知道资源可以继续使用,或者抛出一个JMSException,可以通过<systemUsage>来配置。

  同步发送消息的producer会自动使用producer flow control;对于异步发送消息的producer,要使用producer flow control,你先要为connection配置一个ProducerWindowSize参数,如下:

  ActiveMQConnectionFactory.setProducerWindowSize(1024000);

  ProducerWindowSize是producer在发送消息的过程中,收到broker对于之前发送消息的确认之前,能够发送消息的最大字节数。

  可以禁用producer flow control,以下是ActiveMQ配置文件的一个例子。  

 
    <destinationPolicy>
            <policyMap>
              <policyEntries>
                <policyEntry queue=">" producerFlowControl="false"/>              
        </policyEntries> </policyMap> </destinationPolicy>
 

  注意:自从ActiveMQ 5.x中引入新的消息游标之后,非持久化消息被分流到了临时文件存储中,以此来减少非持久化消息传送使用的内存总量。

  结果就是,你可能会发现一个队列的内存限制永远达不到,因为游标不需要使用太多的内存。如果你真的想把所有的非持久化消息存放到内存中,并在达到内存限制的时候停掉生产者,你需要配置<vmQueueCursor>,示例如下:

<policyEntry queue">" producerFolwControl="true" memoryLimit="1mb">
    <pendingQueuePolicy>
        <vmQueueCursor>
    </pendingQueuePolicy>
 </policyEntry >

  上面的配置可以保证所有的非持久化队列消息都保存在内存中,每一个队列的内存限制为1Mb

  配置客户端异常:为了应对代理空间不足,而导致的不确定的阻塞send()方法的一种替代方案,就是将其配置的成客户端抛出的一个异常,通过将sendFailIfNoSpace属性设置为true,代理将会引起send()方法失败,并抛出javax.jms.ResourceAllocationException异常,传播到客户端,小面是一个配置例子:

 
 <systemUsage>
            <systemUsage sendFailIfNoSpace="true">
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="70" />
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>
 

  这么配置的好处是:客户端可以捕获javax.jms.ResourceAllocationException异常,稍等一下,并重试send()操作,而不是无限期的傻等下去。

  从5.3.1版本之后,sendFailIfNoSpaceAfterTimeout属性才被加进来。这个属性同样导致send()方法失败,并在客户端抛出异常,但仅当等待了指定时间之后才触发。如果配置的等待时间过去之后,代理上的空间仍然没有释放,仅当这个时候send()方法才会失败,并且在客户端抛出异常。示例:

 
 <systemUsage>
            <systemUsage sendFailIfNoSpaceAfterTimeout="3000">
                <memoryUsage>
                    <memoryUsage percentOfJvmHeap="70" />
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>
 

  可以通过<systemUsage>元素的一些属性来减慢生产者,如下例子:

 
 <systemUsage>
            <systemUsage sendFailIfNoSpace="true">
                <memoryUsage>
                    <memoryUsage limit="64 mb"/>
                </memoryUsage>
                <storeUsage>
                    <storeUsage limit="100 gb"/>
                </storeUsage>
                <tempUsage>
                    <tempUsage limit="50 gb"/>
                </tempUsage>
            </systemUsage>
        </systemUsage>
 

  可以为非持久化的消息设置内存限制,为持久化消息设置磁盘空间,以及为临时消息设置总的空间,broker将在减慢生产者之前使用这些空间。具体上述的默认设置,broker将会一直阻塞send()方法的调用,直至一些消息被消费,有了可用的空间。

原文 ActiveMQ学习笔记(16)----Message Dispatch高级特性(二)

posted @ 2019-05-13 08:15  xiaoshen666  阅读(254)  评论(0编辑  收藏  举报