一、通配符
一般情况下,我们使用层次结构的方式来组织队列,比如A.B.C.D,这样便于归类和管理。
我们也可以使用通配符来配置或是操作多个队列。
通配符有三个:
. 用来分隔路径
* 用来匹配路径中的一节
> 用来匹配任意节的路径
订阅信息 | 解释 |
---|---|
PRICE.> | Any price for any product on any exchange |
PRICE.STOCK.> | Any price for a stock on any exchange |
PRICE.STOCK.NASDAQ.* | Any stock price on NASDAQ |
PRICE.STOCK.*.IBM | Any IBM stock price on any exchange |
从5.5 版本以后,可以自定义路径分隔符:
<plugins>
.....
<destinationPathSeparatorPlugin/>
</plugins>
此时FOO.BAR.* 可以表示为 FOO/BAR/*
也可以通过 pathSeparator 属性定义其他符号位路径分隔符。二、队列选项
队列选项是给consumer在JMS规范之外添加的功能特性,通过在队列名称后面使用类似URL的语法添加多个选项。
选项 | 默认值 | 描述 |
---|---|---|
consumer.prefetchSize | 不定 | consumer持有的未确认最大消息数量 参见:prefetch。 |
consumer.maximumPendingMessageLimit | 0 | 控制非持久主题在慢消费(slow consumer)情况下丢弃消息的最大数量。 |
consumer.noLocal | false | |
consumer.dispatchAsync | true | 是否异步分发,参见 dispatch messages asynchronously。 |
consumer.retroactive | false | 是否为回溯消费者 Retroactive Consumer. |
consumer.selector | null | JMS Selector. |
consumer.exclusive | false | 是否为独占消费者 Exclusive Consumer. |
consumer.priority | 0 | 配置消费者优先级 Consumer Priority. |
配置示例:
queue=new ActiveMQQueue("TEST.QUEUE?consumer.dispatchAsync=false&consumer.prefetchSize=10");
consumer=session.createConsumer(queue);
三、消息独占消费
我们经常希望维持队列中的消息,按一定次序转发给消息者。然而当有多个JMS Session和消息消费者实例的从同一个队列中获取消息的时候,就不能保证消息顺序处理。因为消息被多个不同线程并发处理着。在ActiveMQ4.x中可以采用Exclusive Consumer或者Exclusive Queues,避免这种情况,Broker会从消息队列中,一次发送消息给一个消息消费者来保证顺序。
配置如下:
// consumer.exclusive=true 消费独占,也就是只能有一个消费者消费
Destination destination = session.createQueue("queue.exclusive?consumer.exclusive=true");
// 消费者,消息接收者
MessageConsumer consumer = session.createConsumer(destination);
A.当在接收信息的时候有一个或者多个备份接收消息者和一个独占消息者的同时接收时候,无论两者创建先后,在接收的时候,均为独占消息者接收。
B.当在接收信息的时候,有多个独占消费者的时候,只有一个独占消费者可以接收到消息。
C.当有多个备份消息者和多个独占消费者的时候,当所有的独占消费者均close的时候,只有一个备份消费者接到到消息。
备注:再生产环境可用使用该特性,启动多个消费者来提高服务的可用性。
四、组合队列
当你想把同一个消息一次发送到多个消息队列,那么可以在客户端使用组合队列。
// send to 3 queues as one logical operation
Queue queue = new ActiveMQQueue("FOO.A,FOO.B,FOO.C");
producer.send(queue, someMessage);
当然,也可以混合使用队列和主题,只需要使用前缀:queue:// 或 topic://
// send to queues and topic one logical operation
Queue queue = new ActiveMQQueue("FOO.A,topic://NOTIFY.FOO.A");
producer.send(queue, someMessage);
还有一种更透明的方式是在broker端使用,需要配合虚拟队列。
参考:http://activemq.apache.org/composite-destinations.html
五、配置启动队列
虽然ActiveMQ可以在使用的时候自动创建队列,但有些情况下配置启动时创建还是很有必要的:例如配置了安全设置以后使用队列的用户没有创建的权限。此时只需要在配置文件的broker节点添加需要启动时创建的队列即可:
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://activemq.apache.org/schema/core http://activemq.apache.org/schema/core/activemq-core.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
<broker xmlns="http://activemq.apache.org/schema/core">
<destinations>
<queue physicalName="FOO.BAR" />
<topic physicalName="SOME.TOPIC" />
</destinations>
</broker>
</beans>
六、删除不活动的队列
一般情况下,ActiveMQ的queue在不使用之后,可以通过web控制台或是JMX方式来删除掉。
当然,也可以通过配置,使得broker可以自动探测到无用的队列(一定时间内为空的队列)并删除掉,回收响应资源。
配置如下:
<broker xmlns="http://activemq.apache.org/schema/core" schedulePeriodForDestinationPurge="10000">
<destinationPolicy>
<policyMap>
<policyEntries>
<policyEntry queue=">" gcInactiveDestinations="true" inactiveTimoutBeforeGC="30000"/>
</policyEntries>
</policyMap>
</destinationPolicy>
</broker>
schedulePeriodForDestinationPurge:10000 每十秒检查一次,默认为0,此功能关闭gcInactiveDestinations: true 删除掉不活动队列,默认为false
inactiveTimoutBeforeGC:30000 不活动30秒后删除,默认为60秒
由于ActiveMQ使用时自动创建Destination,并且默认情况下不会删除掉,这种只增加不减少,导致在queue创建频繁的情况下,本功能非常有用。