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-查询缓存之中的一个级缓存 查询缓存 一级缓存 一级缓存工作原理 一级缓存測试 一级缓存应用 ...
随机推荐
- tp5控制器调用,方法调用
<?php //命名空间 namespace app\index\controller; use app\admin\controller\Deer; class User{ public ...
- Codeforces 994A. Fingerprints
题意 从x数组中找到最多的y数组中有的数字,按在x数组中出现的顺序输出. 注意 这题x数组和y数组都不会出现重复数字. 代码 #include <bits/stdc++.h> using ...
- Win10 八步打通 Nuget 发布打包
我们可以使用Nuget 下载你所需要的资源包还可以将自己封装好的各种控件包 工具包 等上传nuget 我们只需要几步就完成你要发布的包. 第一步:编译你的控件 anycpu debug/release ...
- 「JavaSE 重新出发」05.03.02 在运行时使用反射分析对象
在编写程序时,如果知道想要查看的域名和类型,查看指定的域是一个很容易的事,而利用反射机制可以查看在编译时还不清楚的对象域. java Employee tank = new Employee(&quo ...
- LeetCode(94)Binary Tree Inorder Traversal
题目如下: Python代码: def inorderTraversal(self, root): res = [] self.helper(root, res) return res def hel ...
- Unity "Build failed : Asset is marked as don't save " 解决方案
编译到Android时失败,是字体的原因: -- -- 摘自官方论坛排第二但点赞第一的回答. http://answers.unity3d.com/questions/363963/build-fai ...
- Guitar Pro 的双十一特惠活动,正在如火如荼进行中...
11月11日这个令人兴奋的日子又来了.没错,“双十一”所有网购达人狂欢的日子.同时期待已久的Guitar Pro 也将在“双十一”当天,把福利分享与你我.11月11日Guitar Pro 将在麦软商城 ...
- HDU 5918 Sequence I
题目来源:2016 CCPC 长春站 题意:给出两个序列 a[] , b[] ,如果b1,b2....bm能够与aq,aq+p,aq+2p...aq+(m-1)p对应( q+(m-1)p<=n ...
- Flask-Babel 使用简介(翻译文档)
最近用flask-bable翻译一个项目,在网站上查找到有一个示例文档,地址:http://translations.readthedocs.io/en/latest/flask-babel.html ...
- pytorch 5 classification 分类
import torch from torch.autograd import Variable import torch.nn.functional as F import matplotlib.p ...