基础概念
开篇前先简单铺垫一下,以便于内容的理解:
- broker
指activemq服务器或消息队列
- 消费者(consumer),生产者(productor)
生产者:发送消息到消息队列
消费者:从消息队列中接收消息
服务结构图:
虚拟目的地(Virtual Destinations)
为了更灵活的解耦进行消息配置,activemq支持了虚拟目的地的功能,它允许我们创建逻辑目的地(实际是一个或多个物理目的地),客户端通过它去生产和消费.
虚拟目的地的实现方式有两种:
- 虚拟主题(Virtual Topics)
- 组合目的地(Composite Destinations)
虚拟主题(Virtual Topics)
JMS持久化主题的限制
JMS持久化订阅者创建后拥有唯一的标识和订阅者名称.任何时点根据订阅者标识只有一个连接被激活,一个订阅者标识和名称只有一个消费者被激活,只有一个线程能从给定的逻辑主题订阅者中进行活动消费.这就意味着JMS不能:
- 同一个订阅者标识下进行消息负载均衡
- 消息发布订阅流程中当一个消费者线程死亡后,订阅者进行快速失败
即发布订阅模式,只允许一个订阅者能收到消息,同时当消息未被接收时,订阅者一直处于连接状态
同时JMS提供的队列具备消费者间负载均衡的能力,允许多线程,多流程和多机器参与消息流程.然后通过像消息组(Message Groups)这样的复杂负载均衡粘滞机制去负载均衡维持有序并行执行;
队列给每个逻辑主题订阅者的另一个好处是可以通过JMX监控队列深度,去监控系统性能,同时还能浏览队列.
虚拟主题的价值
虚拟主题的使用中,生产者发送方式跟使用JMS一样,消费者也可以正常接收制定的主题消息.但是如果这个主题是虚拟的,消费者可以通过队列去订阅逻辑主题,实现负载均衡.
- 虚拟主题使用
生产者定义主题时增加虚拟主题标识前缀.如比如主题名为Orders,则虚拟主题名为:VirtualTopic.Orders
消费者定义接收队列为:比如有两个系统订阅该Orders主题,他们的消费者标识和名称分别为clientID_A和A,clientID_B和B.则其队列名称应该为:A系统的消费者队列名是Consumer.A.VirtualTopic.Orders,B系统的消费者队列名是Consumer.B.VirtualTopic.Orders;
这样每个系统都可以拥有一个消费者池(每个系统有多个消费者,但是只要一个成功即可)去竞争消费消息,以实现内部负载均衡.
组合目的地(Composite Destinations)
组合目的地是从虚拟目的地映射到一组物理目的地.实现指定目的地的一对多关系.它的主要使用场景是组合队列,如当消息发送给队列A时,同时转发到队列B,C和主题D.它通过在broker端进行映射配置,客户端无感知.这与客户端组合目的地使用url进行指定物理目的地发送不同.
<destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<compositeQueue name="MY.QUEUE">
<forwardTo>
<queue physicalName="FOO" />
<topic physicalName="BAR" />
</forwardTo>
</compositeQueue>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
默认,订阅者直接从组合主题或队列消费消息,因为它只是一个逻辑结构.从上面的配置中只能从FOO,BAR中消费消息,不能从MY.QUEUE中.