ActiveMQ学习笔记(14)----Destination高级特性(二)
1. Visual Destinations
1.1 概述
虚拟Destination用来创建逻辑Destinations,客户端可以通过它来产生和消费消息,它会把消息映射到物理Destinations。ActiveMQ支持两种方式:
1. 虚拟主题(Virtual Topics)
2. 组合Destinations (Composite Destinations)
1.2 为何使用虚拟主题
ActiveMQ中,topic只有在持久订阅下才会持久化,持久订阅时,每个订阅者,都相当于一个queue的客户端,它会收取所有消息,这种情况下存在两个问题:
1. 同一个应用内的consumer端负载均衡的问题,也就是同一个应用上的一个持久订阅者不能使用多个consumer来共同承担消息处理功能,因为每个consumer都会获取所有消息。
2. 同一应用内的consumer端的failover问题:由于只能使用单个的持久订阅者,如果这个订阅者出错,则应用就无法处理消息了,系统的健壮性不高。
为了解决这两个问题,ActiveMQ中实现了虚拟的Topic的功能。
1.3 如何使用虚拟主题
1. 对于消息发布者来说,就是一个正常的Topic,名称以VirtualTopic开头。例如
VirtualTopic.Orders.代码示例如下:
Topic destination = session.createTopic("VirtualTopic.Orders");
2. 对于消息接收端来说,是一个队列,不同应用里面应使用不同的前缀作为队列的名称,即可表明自己的身份,即可实现消费端应用的分组。
例如Consumer.A.VritualTopic.Orders,说明它是名称A的消费端,同理Consumer.B.VritualTopic.Orders表示时一个名称为B的客户端,可以在同一个应用里面使用多个consumer消费此queue,则可以实现上面两个功能。
又因为不同应用使用的queue名称不同(前缀不同),所以不同的应用中都可以接收到全部的消息,每个客户端相当于一个持久订阅者,而且这个客户端可以使用多个消费者来共同承担消费任务,代码示例如下:
Destination destiantion = session.createQueue("Consumer.A.VirtualTopic.Orders“);
完整得测试代码如下:
消息发送者
package com.wangx.activemq.topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class TopicSender {
public static void main(String[] args) throws JMSException {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//创建虚拟主题,加前缀VirtualTopic
Topic topic = session.createTopic("VirtualTopic.myTopic");
MessageProducer producer = session.createProducer(topic);
producer.setDeliveryMode(DeliveryMode.PERSISTENT);
connection.start();
for (int i = 0; i < 30; i++) {
TextMessage textMessage = session.createTextMessage("topic消息===" + i);
producer.send(textMessage);
}
session.commit();
connection.close();
}
}
A客户端代码(只有一个消费者)
package com.wangx.activemq.topic; import org.apache.activemq.ActiveMQConnectionFactory; import javax.jms.*;
public class QR1 { public static void main(String[] args) throws JMSException {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
connection.start();
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//创建队列
Destination destination = session.createQueue("Consumer.A.VirtualTopic.myTopic");
MessageConsumer consumer = session.createConsumer(destination); consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("Consumer.A.接收到得消息:" + textMessage.getText());
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
}); }
}
B客户端代码,有两个消费者
package com.wangx.activemq.topic;
import org.apache.activemq.ActiveMQConnectionFactory;
import javax.jms.*;
public class QR2 {
public static void main(String[] args) throws JMSException {
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://localhost:61616");
Connection connection = factory.createConnection();
connection.start();
final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
//创建队列
Destination destination = session.createQueue("Consumer.B.VirtualTopic.myTopic");
final MessageConsumer consumer = session.createConsumer(destination);
final MessageConsumer messageConsumer = session.createConsumer(destination);
//模拟多个consumer消费一个queue
new Thread(new Runnable() {
@Override
public void run() {
try {
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("Consumer.B-->consumer接收到消息:" + textMessage.getText());
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage) message;
try {
System.out.println("Consumer.B-->messageConsumer接收到消息:" + textMessage.getText());
session.commit();
} catch (JMSException e) {
e.printStackTrace();
}
}
});
} catch (JMSException e) {
e.printStackTrace();
}
}
}).start();
}
}
在接收消息之前,应该先运行一下consumer客户端,将消费者注册到Broker中。
3. 默认虚拟主题得前缀是:VirtualTopic.>
自定义消费虚拟地址默认格式:Consumer.*.VirtualTopic.>
自定义消费虚拟地址可以改,比如下面的配置就把它修改了。
xml配置如下
<broker xmlns="http:/activemq.apache.org/schema/core"> <destinationInterceptors>
<virtualDestinationInterceptor>
<virtualDestinations>
<virtualTopic name=">" prefix="VirtualTopicConsumers.*." selectorAware="false"/>
</virtualDestinations>
</virtualDestinationInterceptor>
</destinationInterceptors>
</broker>
配置之后将consumer端的相应前缀修改即可。
2. Mirrored Queues
2.1 概述
ActiveMQ中每个queue中的消息只能被一个consumer消费,然而,有时候你可能希望能够监视生产者和消费者之间的消息流。你可以通过Virtual Destinations来建立一个virtual queue 来把消息发送到多个queues中。但是,为系统中没给queue都进行如此配置可能会很麻烦。
2.1使用
ActiveMQ支持Mirrored Queues。Broker会把发送到某个queue的所有消息都转发到一个名称类似的topic,因此监控程序只需要订阅这个mirrored queue topic。为了启用Mirrored Queues,首先将Broker Service的useMirroredQueues属性设置成true,然后可以通过destinationInterceptors设置其他属性,如:mirror topic的前缀,缺省是:“VirtualTopic.Mirror.".
比如修改后的配置如下
<destinationInterceptors>
<mirroredQueue copyMessage="true" postfix=".qmirror" prefix=""/>
</destinationInterceptors>
在我的配置中并没有配置配置前缀,但是一定需要配置copyMessage="true",查看控制台如下

存在默认前缀的topic,此时只需要用一个消费者去消费该topic中的消息就可以了。
3. Per Destination Policies
ActiveMQ支持多种不同的策略,来单独配置每一个Destination,它的属性很多,可以参考官方文档:
http://activemq.apache.org/per-destination-policies.html
官方文档最后还给出了一个demo做参考。
ActiveMQ学习笔记(14)----Destination高级特性(二)的更多相关文章
- Python 学习笔记 之 02 - 高级特性总结
切片 语法: li.[x:y:z] li为list.tuple等数据类型,x为开始进行切片的位置,y为切片停止的位置(不包含y),z为xy切片后的结果里,每间隔z个元素输出一次结果. x默认为0 ...
- ActiveMQ中的Destination高级特性(一)
---------------------------------------------------------------------------------------- Destination ...
- 分布式-信息方式-ActiveMQ的Destination高级特性1
ActiveMQ的Destination高级特性 Destination高级特性----->Composite Destinations 组合队列Composite Destinations : ...
- ActiveMQ学习笔记(5)——使用Spring JMS收发消息
摘要 ActiveMQ学习笔记(四)http://my.oschina.net/xiaoxishan/blog/380446 中记录了如何使用原生的方式从ActiveMQ中收发消息.可以看出,每次 ...
- 基于.net的分布式系统限流组件 C# DataGridView绑定List对象时,利用BindingList来实现增删查改 .net中ThreadPool与Task的认识总结 C# 排序技术研究与对比 基于.net的通用内存缓存模型组件 Scala学习笔记:重要语法特性
基于.net的分布式系统限流组件 在互联网应用中,流量洪峰是常有的事情.在应对流量洪峰时,通用的处理模式一般有排队.限流,这样可以非常直接有效的保护系统,防止系统被打爆.另外,通过限流技术手段,可 ...
- C++ 学习笔记(一些新特性总结3)
C++ 学习笔记(一些新特性总结3) public.protected 和 private 继承 public 继承时,基类的存取限制是不变的. class MyClass { public: // ...
- Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法
Ext.Net学习笔记14:Ext.Net GridPanel Grouping用法 Ext.Net GridPanel可以进行Group操作,例如: 如何启用Grouping功能呢?只需要在Grid ...
- SQL反模式学习笔记14 关于Null值的使用
目标:辨别并使用Null值 反模式:将Null值作为普通的值,反之亦然 1.在表达式中使用Null: Null值与空字符串是不一样的,Null值参与任何的加.减.乘.除等其他运算,结果都是Null: ...
- golang学习笔记14 golang substring 截取字符串
golang学习笔记14 golang substring 截取字符串golang 没有java那样的substring函数,但支持直接根据 index 截取字符串mystr := "hel ...
- mybatis学习笔记(14)-查询缓存之中的一个级缓存
mybatis学习笔记(14)-查询缓存之中的一个级缓存 标签: mybatis mybatis学习笔记14-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...
随机推荐
- Primitive data types recap
- 谁说NTFS不支持UEFI启动的?启动U盘放不了超过4G的文件怎么办?Server2016 Win10 U盘UEFI启动制作方法
大家都知道,我们平时做启动盘,用得最多的就是UltraISO(软碟通)这个工具了.用它我们可以很简单快速的把一个空白的普通U盘制作成一个PE启动U盘或系统U盘,然后用它来安装系统非常的方便,受到了广大 ...
- hdu 1240(三维广搜)
题意: 有一个n*n*n的三维空间. 给你起始坐标和终点坐标.要你从起点到终点,问最少需要多少步走出去.如果走不出去则输出"NO ROUTE". 空间中 'O' 表示这个点可以走, ...
- BZOJ 4229: 选择 LCT_独创方法_边双
考虑如果两点在一个环中,那么这两点一定可以构出双联通分量. 考虑环和环镶嵌,那么两个环中的点一定都互为双联通分量. 由此,我们想到一个算法: 将删边转为反向加边,用LCT维护图. 当我们连接两个点时, ...
- springboot中文文档
http://blog.geekidentity.com/spring/spring_boot_translation/ https://blog.csdn.net/zfrong/article/de ...
- 如何让Jboss的debug在myeclise上运行
1.在windows下运行jboss的debug.bat 看见监听的端口 2.打开myeclipse 点击选择 ①你要配置的名字(随意) ②myeclipse中选中该项目 ③jboss的启动的ip地址 ...
- 【BZOJ 1211】 [HNOI2004]树的计数
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] prufer数列的应用 http://www.cnblogs.com/AWCXV/p/7626625.html 这一题没有节点的度数 ...
- Tarjan缩点【模板】
#include <algorithm> #include <cstdio> #include <map> using namespace std; ); map& ...
- vue中export default 在console中是this.$vm
vue中export default 在console中是this.$vm 用vue-cli搭出框架,用webstorm进行开发,参考vue2的官网进行教程学习, 在vue-cli中是用es6的exp ...
- Android_通过Bugtags平台,方便測试人员提交bug及整个bug系统的管理
Bugtags 是什么? Bugtags 是一款缺陷发现及管理工具. 当您的 App 集成了 Bugtags SDK 后,測试人员就可直接在 App 里所见即所得的提交 Bug. SDK 会自己主动截 ...