郑重提示,本文转载自http://shift-alt-ctrl.iteye.com/blog/2065436
ActiveMQ提供了虚拟通道的特性(Virtual Destination),它允许一个逻辑通道(logical destination)映射成一个或者多个物理通道(physical destination);它可以非常灵活的解决"消息整合"方面的问题,它可以实现:
1) 提供了VirtualTopic特性,可以让一个订阅者的消息列表,作为Queue来消费。
2) 提供了Composite特性,可以把一个逻辑通道中的消息,转发到任意多的物理通道中。
一. VirtualTopic
Topic最大的限制就是同一个ClientId的订阅者,任何时刻只能有一个活跃。所以我们在分布式部署时,就会很麻烦,比如一个应用部署成多个实例,且它们都有相同的Topic Consumer配置,那么意味着
一个实例部署成功后,其它的实例都会因为无法订阅Topic而导致故障;同时也意味着,如果这个Topic Consumer失效后,我们不能自动让其他Consumer的接管它。但是Queue却没有这些限制,因为Queue可以同时有任意多个消费者,它们可以并发的消费消息,从而实现“负载均衡”。如果我们期望Topic也能如此,那么可以用VirtualTopic。
- <broker xmlns="http://activemq.apache.org/schema/core">
- <destinationInterceptors>
- <virtualDestinationInterceptor>
- <virtualDestinations>
- <virtualTopic name=">" prefix="VConsumers.*." selectorAware="false"/>
- </virtualDestinations>
- </virtualDestinationInterceptor>
- </destinationInterceptors>
- </broker>
对于所有的VirtualTopic,它们的namespace一定是"VirtualTopic.",Broker将会根据此namespace来判定逻辑通道是否为VirtualTopic,反过来说,如果你希望一个逻辑通道是一个VirtualTopic,那么它必须以“VirtualTopic.”作为前缀。比如“VirtualTopic.order”,那么它就是一个VirtualTopic,它的物理通道名称为"order"。
对于Producer端,需要按照正常的Topic发送消息,通道名称为逻辑通道全名:
- Topic topic = session.createTopic("VirtualTopic.order");
- MessageProducer producer = session.createProducer(topic);
- //producer.send(message);
VirtualTopic对Consumer而言,是一个逻辑的Queue,Queue的全名有上述配置文件中的“prefix” + Client标识 + 逻辑虚拟通道;假如“Client标识”为"dbcenter"【相当于ClientId】,用来订阅Order消息,那么最终逻辑Queue的全名为:"VConsumers.dbcenter.VirtualTopic.order",其中需要注意prefix中的"*"占位符就是用来替换“Client标识”的;Broker端默认的prefix为"Consumer.*."。当然我们还可以postfix【后缀】,不过通常没有必要。
- Queue queue = session.createQueue("VConsumers.dbcenter.VirtualTopic.order");
- MessageConsumer consumer = session.createConsumer(queue);
对于Order通道而言,“dbcenter”相当于是一个订阅者;Broker将dbcenter订阅的消息转发到了“VConsumers.dbcenter.VirtualTopic.order”队列中;最重要的一点,这个虚拟Queue完全具有队列的所有特性,它的Consumer可以并行消费。
其中还有一个重要的参数"selectorAware",它表示从Topic中将消息转发给Queue时,是否关注Consumer的selector情况。如果为false,那么Topic中的消息全部转发给Queue,否则只会转发匹配Queue Consumer的selector的消息。需要非常注意,当selectorAware为true时,如果消息不匹配任何selector或者Queue中没有任何Consumer活跃,那么消息将不会转发给Queue。
VirtualTopic仍然可以被正常的订阅者消费,即:
- Topic topic = session.createTopic("VirtualTopic.order");
- TopicSubscriber subscriber = session.createDurableSubscriber(topic,"dbcenter");
同时需要注意,VirtualTopic只会转发“Client标识”注册之后的消息,且即使Queue消费了消息,VirtualTopic中的消息仍然不会被删除(看起来仍然是Dequeued=0),对于Broker而言,逻辑Queue不被认为是一个“Durable Subscriber”,只有真正的Subscriber消费消息后,Topic中的消息才会Dequeue。不过消息Dequeue后,不会影响Queue中的消息,因为这是基于Copy的。
到目前为止,我尚不清楚,如果VirtualTopic中没有真正的Subscriber,这些消息该如何Dequeue。
当真正的subscriber和Queue都同时存在VirtualTopic中的时候,而且你的broker架构采用了“forward-brige”结构,那么你需要增加如下配置来避免消息的重复转发问题。在forward-brige架构中,任何通道中的消息都会forward到其他network node中(其他broker上),当然这个虚拟的Queue的消息也不例外。
- <networkConnectors>
- <networkConnector uri="static://(tcp://localhost:61617)">
- <excludedDestinations>
- <!-- prefix和VirtualTopic保持一致
- <queue physicalName="VConsumer.*.VirtualTopic.>"/>
- </excludedDestinations>
- </networkConnector>
- </networkConnectors>
二. Composite Destinations
复合通道,它允许一条消息在多个物理通道间转发,就像一个通道映射成多个一样(one-many);比如复合通道A,映射成B和C,那么发往A的消息会同时转发给B和C,那么消费者可以直接通过B或者C获取消息;
这是一种实现消息复制转发、通道映射的便捷办法。复合通道包括CompositeQueue和CompositeTopic两种。
- <broker persistent="false" useJmx="false" xmlns="http://activemq.apache.org/schema/core">
- <destinationInterceptors>
- <virtualDestinationInterceptor>
- <virtualDestinations>
- <compositeQueue name="order">
- <forwardTo>
- <queue physicalName="order.dbcenter" />
- <topic physicalName="order.statistic" />
- </forwardTo>
- </compositeQueue>
- <!--
- <compositeTopic name="order" forwardOnly="false">
- <forwardTo>
- <queue physicalName="order.dbcenter" />
- <topic physicalName="order.statistic" />
- </forwardTo>
- </compositeTopic>
- -->
- </virtualDestinations>
- </virtualDestinationInterceptor>
- </destinationInterceptors>
- </broker>
上述配置forwardOnly属性表示发往CompositeQueue中的消息是否“仅仅转发,而不本地保留”,如果forwardOnly为true,那么消息将不会在order队列中保留,即order队列中不会有任何消息。如果为false,那么消息将会转发完成后,添加到order中,消费者仍然可以消费order队列中的消息。无论是Compsite通道还是转发的通道,它们和普通的通道没有任何区别,开发者仍然可以像使用普通的通道一样使用它们(消费消息和发送消息)。
很多时候,我们希望在转发消息时,能够使用selector,此时我们可以使用filteredDestination,这样我们可以消息转发时控制消息。
- <compositeQueue name="MY.QUEUE">
- <forwardTo>
- <filteredDestination selector="orderType = 1" queue="food.order"/>
- <filteredDestination selector="status = 1" topic="order.statistic"/>
- </forwardTo>
- </compositeQueue>
相关推荐
### ActiveMQ虚拟Topic与路由功能详解 在ActiveMQ消息中间件中,为了更好地实现消息的分发和管理,引入了虚拟Topic(Virtual Topic)的概念。本文将深入探讨虚拟Topic及路由功能,帮助读者理解如何利用这些特性来...
基于SpringBoot开发的ActiveMQ虚拟主题客户端,达到消费者多点消费、负载均衡和故障转移的目的。 详情可以参考这里: https://my.oschina.net/noryar/blog/1573047 https://my.oschina.net/noryar/blog/1575003
总的来说,通过SpringBoot与ActiveMQ的整合,我们可以轻松地在分布式系统中实现异步通信和解耦,提高系统的稳定性和性能。通过理解和实践上述知识点,你将能够熟练地在SpringBoot项目中运用ActiveMQ实现消息队列的...
本篇将详细介绍如何将ActiveMQ与Tomcat进行整合,以便在Web应用程序中利用ActiveMQ的消息传递功能。 首先,我们需要了解ActiveMQ和Tomcat的基本概念。ActiveMQ是Apache软件基金会开发的一款开源JMS(Java Message ...
"ActiveMQ5.13 安装与配置" ActiveMQ 是 Apache 软件基金会提供的一个开源message broker,能够实现点对点(Point-to-Point)和发布/订阅(Publish/Subscribe)模式的消息传递。ActiveMQ 5.13 是 ActiveMQ 的一个...
5. **ActiveMQ与Quartz的结合**:在某些场景下,可能需要结合使用,例如,Quartz可以定时触发向ActiveMQ发送消息的任务,以实现定时推送服务。 6. **实战示例**:压缩包中的"ActiveMQ_Test2"可能是一个Java项目,...
接下来我们将详细阐述ActiveMQ的安装与使用过程,包括安装前提条件、安装步骤、配置和启动以及安全配置等知识点。 首先,安装ActiveMQ之前需要有一个Java运行环境。这是因为ActiveMQ是使用Java开发的。JDK(Java ...
【ActiveMQ与Tomcat整合教程】是关于如何在Apache Tomcat服务器中集成开源消息中间件ActiveMQ的详细步骤。这个教程适用于Tomcat 6.0.14版本,但请注意不同版本可能存在配置上的差异。 首先,为了使Tomcat能够识别和...
5. **连接工厂与会话**:了解JMS中的连接工厂和会话对象,它们是与消息服务器建立连接并创建消息通道的基础。 6. **消息生产者与消费者**:掌握如何使用ActiveMQ收发工具创建消息生产者发送消息,以及创建消息消费...
ActiveMQ与Spring线程池整合的一个实例。 lib库没有上传。 对于实例的讲解,在竹子的论坛有我对这个实例的帖子(http://www.java2000.net/viewthread.jsp?tid=1167) lib中包含: apache-activemq-4.1.1.jar ...
《ActiveMQ与Spring整合源代码解析》 ActiveMQ和Spring的整合是企业级应用中常见的一种技术组合,尤其在分布式系统和微服务架构中,消息队列(Message Broker)如ActiveMQ扮演着至关重要的角色。它能有效地实现系统...
本篇将详细讲解如何将ActiveMQ与Spring进行整合封装,实现高效、便捷的消息服务。 首先,ActiveMQ与Spring的整合主要基于Spring的JMS(Java Message Service)支持。Spring通过`ConnectionFactory`和`Destination`...
**ActiveMQ与REST API实践** ActiveMQ是Apache软件基金会开发的一款开源消息中间件,它遵循开放消息中间件标准——Java Message Service(JMS)。ActiveMQ以其高性能、稳定性和丰富的特性在分布式系统中广泛使用,...
2. **JMS编程**:使用JMS API与ActiveMQ交互,创建ConnectionFactory,然后创建Connection,Session,Destination(Queue或Topic),最后创建MessageProducer和MessageConsumer。 3. **Web控制台**:ActiveMQ内置了...
将ActiveMQ与Spring进行整合,可以方便地在Spring应用中使用消息队列功能。 本案例主要展示了如何在Spring应用中集成ActiveMQ,实现消息的发送和接收。首先,我们需要在项目中引入ActiveMQ的相关依赖。在Maven工程...
**ActiveMQ与Spring整合详解** ActiveMQ是Apache组织开发的一款开源消息中间件,它遵循Java消息服务(JMS)规范,提供可靠的消息传递和高效的消息处理能力。在企业级应用中,ActiveMQ常用于实现应用之间的解耦,...
标题中的“ActiveMQ与Zookeeper集群测试代码”指的是一个实验或示例项目,旨在演示如何结合这两个组件来构建高可用的消息传递环境。Zookeeper在这里的角色可能是用来管理ActiveMQ集群的状态,实现节点间的选举和故障...
3. 路由和过滤:ActiveMQ提供丰富的消息路由和过滤选项,如主题(Topics)、队列(Queues)、虚拟主题(Virtual Topics)等,可以根据业务需求定制消息的分发策略。 4. 事务和持久化:ActiveMQ支持事务性消息处理,...
标题中的“ActiveMQ与Spring集成实例之使用Maven构建”是指在Java开发环境中,通过Maven构建工具将Apache ActiveMQ消息中间件与Spring框架整合在一起的实际操作案例。这个主题涵盖了几大关键知识点: 1. **Apache ...
- **ActiveMQ-CPP 定义**:ActiveMQ-CPP 是一个用于与 ActiveMQ 服务器交互的 C++ API 库。它为 C++ 开发者提供了访问 ActiveMQ 的接口,从而使开发者能够在 C++ 应用程序中轻松地集成消息队列服务。 - **Winkeemq-...