ActiveMQ之虚拟主题
来源:互联网 发布:adobe cc mac 编辑:程序博客网 时间:2024/04/29 16:34
1.虚拟主题(Virtual Topics)
2.组合 Destinations(CompositeDestinations)
这两种虚拟Destinations可以看做对简单的topic和queue用法的补充,基于它们可以实现一些简单有用的EIP功能,虚拟主题类似于1对多的分支功能+消费端的cluster+failover,组合Destinations类似于简单的destinations直接的路由功能。
虚拟主题(Virtual Topics)
ActiveMQ中,topic只有在持久订阅(durablesubscription)下是持久化的。存在持久订阅时,每个持久订阅者,都相当于一个持久化的queue的客户端,它会收取所有消息。这种情况下存在两个问题:
1.同一应用内consumer端负载均衡的问题:同一个应用上的一个持久订阅不能使用多个consumer来共同承担消息处理功能。因为每个都会获取所有消息。queue模式可以解决这个问题,broker端又不能将消息发送到多个应用端。所以,既要发布订阅,又要让消费者分组,这个功能jms规范本身是没有的。
2.同一应用内consumer端failover的问题:由于只能使用单个的持久订阅者,如果这个订阅者出错,则应用就无法处理消息了,系统的健壮性不高。
为了解决这两个问题,ActiveMQ中实现了虚拟Topic的功能。使用起来非常简单。
对于消息发布者来说,就是一个正常的Topic,名称以VirtualTopic.开头。例如VirtualTopic.TEST。
对于消息接收端来说,是个队列,不同应用里使用不同的前缀作为队列的名称,即可表明自己的身份即可实现消费端应用分组。例如Consumer.A.VirtualTopic.TEST,说明它是名称为A的消费端,同理Consumer.B.VirtualTopic.TEST说明是一个名称为B的客户端。可以在同一个应用里使用多个consumer消费此queue,则可以实现上面两个功能。又因为不同应用使用的queue名称不同(前缀不同),所以不同的应用中都可以接收到全部的消息。每个客户端相当于一个持久订阅者,而且这个客户端可以使用多个消费者共同来承担消费任务。
生产者:
package cn.slimsmart.activemq.demo.virtualtopic;import javax.jms.Connection;import javax.jms.DeliveryMode;import javax.jms.JMSException;import javax.jms.MessageProducer;import javax.jms.Session;import javax.jms.TextMessage;import javax.jms.Topic;import org.apache.activemq.ActiveMQConnectionFactory;public class Producer {public static void main(String[] args) throws JMSException {// 连接到ActiveMQ服务器ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.18.67:61616");Connection connection = factory.createConnection();connection.start();Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);// 创建主题Topic topic = session.createTopic("VirtualTopic.TEST");MessageProducer producer = session.createProducer(topic);// NON_PERSISTENT 非持久化 PERSISTENT 持久化,发送消息时用使用持久模式producer.setDeliveryMode(DeliveryMode.PERSISTENT);TextMessage message = session.createTextMessage();message.setText("topic 消息。");message.setStringProperty("property", "消息Property");// 发布主题消息producer.send(message);System.out.println("Sent message: " + message.getText());session.close();connection.close();}}
消费者:
package cn.slimsmart.activemq.demo.virtualtopic;import javax.jms.Connection;import javax.jms.JMSException;import javax.jms.Message;import javax.jms.MessageConsumer;import javax.jms.MessageListener;import javax.jms.Queue;import javax.jms.Session;import javax.jms.TextMessage;import org.apache.activemq.ActiveMQConnectionFactory;public class Consumer {public static void main(String[] args) throws JMSException, InterruptedException {// 连接到ActiveMQ服务器ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.18.67:61616");Connection connection = factory.createConnection();connection.start();Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);// 创建主题 Queue topicA = session.createQueue("Consumer.A.VirtualTopic.TEST");Queue topicB = session.createQueue("Consumer.B.VirtualTopic.TEST");// 消费者A组创建订阅MessageConsumer consumerA1 = session.createConsumer(topicA);consumerA1.setMessageListener(new MessageListener() {// 订阅接收方法public void onMessage(Message message) {TextMessage tm = (TextMessage) message;try {System.out.println("Received message A1: " + tm.getText()+":"+tm.getStringProperty("property"));} catch (JMSException e) {e.printStackTrace();}}});MessageConsumer consumerA2 = session.createConsumer(topicA);consumerA2.setMessageListener(new MessageListener() {// 订阅接收方法public void onMessage(Message message) {TextMessage tm = (TextMessage) message;try {System.out.println("Received message A2: " + tm.getText()+":"+tm.getStringProperty("property"));} catch (JMSException e) {e.printStackTrace();}}});//消费者B组创建订阅MessageConsumer consumerB1 = session.createConsumer(topicB);consumerB1.setMessageListener(new MessageListener() {// 订阅接收方法public void onMessage(Message message) {TextMessage tm = (TextMessage) message;try {System.out.println("Received message B1: " + tm.getText()+":"+tm.getStringProperty("property"));} catch (JMSException e) {e.printStackTrace();}}});MessageConsumer consumerB2 = session.createConsumer(topicB);consumerB2.setMessageListener(new MessageListener() {// 订阅接收方法public void onMessage(Message message) {TextMessage tm = (TextMessage) message;try {System.out.println("Received message B2: " + tm.getText()+":"+tm.getStringProperty("property"));} catch (JMSException e) {e.printStackTrace();}}});session.close();connection.close();}}使用同样queue名称的消费者会平分所有消息。
从queue接收到的消息,message.getJMSDestination().toString()为topic://VirtualTopic.TEST,即原始的destination。消息的persistent属性为true,即每个相当于一个持久订阅。
A1和A2为一个应用,B1和B2为一个应用,2组应用内部做负载,和failover。
Virtual Topic这个功能特性在broker上有个总开关,useVirtualTopics属性,默认为true,设置为false即可关闭此功能。当此功能开启,并且使用了持久化的存储时,broker启动的时候会从持久化存储里拿到所有的destinations的名称,如果名称模式与Virtual Topics匹配,则把它们添加到系统的Virtual Topics列表中去。当然,没有显式定义的Virtual Topics,也可以直接使用的,系统会自动创建对应的实际topic。当有consumer访问此VirtualTopics时,系统会自动创建持久化的queue,并在每次Topic收到消息时,分发到具体的queue。
消费端使用的queue名称前缀的Consumer是可以修改的。示例如下:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:amq="http://activemq.apache.org/schema/core" 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"> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" /> <broker xmlns="http://activemq.apache.org/schema/core"> <destinationInterceptors> <virtualDestinationInterceptor> <virtualDestinations> <virtualTopic name=">"prefix="VirtualTopicConsumers.*."selectorAware="false"/> </virtualDestinations> </virtualDestinationInterceptor> </destinationInterceptors> </broker></beans>前缀修改成了VirtualTopicConsumers。其实也可以使用postfix属性设置后缀(貌似一般没有必要)。selectorAware属性则表明如果consumer端有selector,则只有匹配selector的消息才会分派到对应的queue中去。
- ActiveMQ之虚拟主题
- ActiveMQ高级特性:ActiveMQ之虚拟主题
- activemq spring整合 以及虚拟主题设置
- ActiveMQ之队列和主题
- ActiveMQ之队列和主题
- activemq之主题、队列设置密码
- activemq之主题、队列设置密码
- 主题:消息中间件 activeMQ的源码分析 之 开篇
- ActiveMQ消息中间件之队列模式和主题模式详解
- ActiveMQ实战(三)--ActiveMQ的通信方式之主题发布订阅式(publish-subscribe)
- ActiveMQ与虚拟通道
- ACTIVEMQ主题、队列设置用户名密码
- Windows下配置Apache虚拟主题VirtualHost
- 标题栏、状态栏、虚拟按键、主题。搞一下!
- ActiveMQ系列之五:ActiveMQ的Transport
- ActiveMQ之三:启动ActiveMQ的Broker
- ActiveMQ之composite destinations
- ActiveMQ 之 Topic Persistence
- 《泊秦淮》
- 第二章 身份验证——《跟我学Shiro》
- odoo对象定义的完整属性如下:
- 福鼎做网站的
- 【杂文】 职业生涯中的五个坎
- ActiveMQ之虚拟主题
- 高通编译命令
- SAT题型指导--Sentence Completion
- 第三章 授权——《跟我学Shiro》
- 开机延时启动cmd命令(带关闭)
- 韩姿曼微商是变相的传销吗s1
- Oracle数据库应用,热数据的最佳定义是什么?
- ActiveMQ之高级特性
- 第四章 INI配置——《跟我学Shiro》