概要:


前一章讲解了消费者如何通过通配符来匹配目的地,以实现一个消费者同时接收多个目的地的消息。
对于生产者来讲,可能存在下面的需求:
1. 同一条message可能要发送到多个Queue;
2. 同一条message同时发送到Queue和Topic;等
这时,我们可以使用composite Destination来解决。

下面将介绍如何将message发送到多个Queue、以及将message同时发送到Queue和Topic。


环境:

  1. JmsMessageListener.java
  2. Sender.java
  3. applicationContext-compositeDestination.xml



方式1:同时向多个Queue中发送相同的消息

源文件和配置文件:

JmsMessageListener.java 异步接收消息

  1. package com.ll.compositeDestination;
  2. import javax.jms.JMSException;
  3. import javax.jms.Message;
  4. import javax.jms.MessageListener;
  5. import javax.jms.TextMessage;
  6. public class JmsMessageListener implements MessageListener {
  7. public void onMessage(Message message) {
  8. System.out.println("消息全部内容:" + message.toString());
  9. try {
  10. System.out.println("消息主题:" + message.getJMSDestination().toString());
  11. } catch (JMSException e1) {
  12. e1.printStackTrace();
  13. }
  14. TextMessage tm = (TextMessage) message;
  15. try {
  16. System.out.println("消息体:" + tm.getText());
  17. } catch (JMSException e) {
  18. e.printStackTrace();
  19. }
  20. System.out.println("------------------------------------");
  21. }
  22. }


Sender.java

  1. package com.ll.compositeDestination;
  2. import javax.jms.Destination;
  3. import javax.jms.JMSException;
  4. import javax.jms.Message;
  5. import javax.jms.Queue;
  6. import javax.jms.Session;
  7. import org.apache.activemq.command.ActiveMQQueue;
  8. import org.springframework.context.ApplicationContext;
  9. import org.springframework.context.support.ClassPathXmlApplicationContext;
  10. import org.springframework.jms.core.JmsTemplate;
  11. import org.springframework.jms.core.MessageCreator;
  12. public class Sender {
  13. public static void main(String[] args) {
  14. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
  15. "applicationContext-compositeDestination.xml");
  16. JmsTemplate template = (JmsTemplate) applicationContext
  17. .getBean("jmsTemplate");
  18. Destination destination =(Destination) applicationContext
  19. .getBean("destinationProducer");
  20. // Queue queue = new ActiveMQQueue("FOO.A,FOO.B,FOO.C");
  21. //发送消息
  22. template.send(destination, new MessageCreator() {
  23. public Message createMessage(Session session) throws JMSException {
  24. return session
  25. .createTextMessage("同时向三个Queue中发送相同的消息");
  26. }
  27. });
  28. System.out.println("同时向三个Queue中发送相同的消息-发送完成...");
  29. }
  30. }

applicationContext-compositeDestination.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  6. <!--创建连接工厂 -->
  7. <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
  8. <property name="brokerURL" value="tcp://localhost:61616"></property>
  9. </bean>
  10. <!-- 通配符 供消费者使用 -->
  11. <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
  12. <constructor-arg index="0" value="FOO.*"></constructor-arg>
  13. </bean>
  14. <!-- composite destination 供生产者使用 -->
  15. <bean id="destinationProducer" class="org.apache.activemq.command.ActiveMQQueue">
  16. <constructor-arg index="0" value="FOO.A,FOO.B,FOO.C,FOO.D"></constructor-arg>
  17. </bean>
  18. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  19. <property name="connectionFactory" ref="connectionFactory"></property>
  20. <property name="defaultDestination" ref="destinationProducer"></property>
  21. <property name="receiveTimeout" value="600"></property>
  22. </bean>
  23. <!-- 消息监听接口 -->
  24. <bean id="jmsMessageListener" class="com.ll.compositeDestination.JmsMessageListener">
  25. </bean>
  26. <!-- 消费者,通过消息侦听器实现 -->
  27. <bean id="consumer"
  28. class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  29. <property name="connectionFactory" ref="connectionFactory" />
  30. <property name="destination" ref="destination" />
  31. <property name="messageListener" ref="jmsMessageListener" />
  32. </bean>
  33. </beans>


运行结果:



方式2:同时向Queue中发送相同的消息

环境、jar包和方式1 相同;
总共3个文件:
  1. JmsMessageListener.java
  2. Sender.java
  3. applicationContext-compositeDestination.xml

JmsMessageListener.java

  1. package com.ll.compositeDestination;
  2. import javax.jms.JMSException;
  3. import javax.jms.Message;
  4. import javax.jms.MessageListener;
  5. import javax.jms.TextMessage;
  6. public class JmsMessageListener implements MessageListener {
  7. public void onMessage(Message message) {
  8. System.out.println("消息全部内容:" + message.toString());
  9. try {
  10. System.out.println("消息主题:" + message.getJMSDestination().toString());
  11. } catch (JMSException e1) {
  12. e1.printStackTrace();
  13. }
  14. TextMessage tm = (TextMessage) message;
  15. try {
  16. System.out.println("消息体:" + tm.getText());
  17. } catch (JMSException e) {
  18. e.printStackTrace();
  19. }
  20. System.out.println("------------------------------------");
  21. }
  22. }


Sender.java

  1. package com.ll.compositeDestination;
  2. import javax.jms.Destination;
  3. import javax.jms.JMSException;
  4. import javax.jms.Message;
  5. import javax.jms.Queue;
  6. import javax.jms.Session;
  7. import org.apache.activemq.command.ActiveMQQueue;
  8. import org.springframework.context.ApplicationContext;
  9. import org.springframework.context.support.ClassPathXmlApplicationContext;
  10. import org.springframework.jms.core.JmsTemplate;
  11. import org.springframework.jms.core.MessageCreator;
  12. public class Sender {
  13. public static void main(String[] args) {
  14. ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
  15. "applicationContext-compositeDestination.xml");
  16. JmsTemplate template = (JmsTemplate) applicationContext
  17. .getBean("jmsTemplate");
  18. Destination destination = (Destination) applicationContext
  19. .getBean("destinationProducer");
  20. try {
  21. Thread.sleep(3000);
  22. } catch (InterruptedException e) {
  23. e.printStackTrace();
  24. }
  25. // 发送消息
  26. template.send(destination, new MessageCreator() {
  27. public Message createMessage(Session session) throws JMSException {
  28. return session.createTextMessage("同时向多个Queue、Topic中发送相同的消息");
  29. }
  30. });
  31. }
  32. }


applicationContext-compositeDestination.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
  6. <!--创建连接工厂 -->
  7. <bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
  8. <property name="brokerURL" value="tcp://localhost:61616"></property>
  9. </bean>
  10. <!-- 通配符FOO.* 供消费者使用 -->
  11. <bean id="destination" class="org.apache.activemq.command.ActiveMQQueue">
  12. <constructor-arg index="0" value="FOO.*"></constructor-arg>
  13. </bean>
  14. <!-- 通配符NOTIFY.FOO.* 供消费者使用 -->
  15. <bean id="destination2" class="org.apache.activemq.command.ActiveMQTopic">
  16. <constructor-arg index="0" value="NOTIFY.FOO.*"></constructor-arg>
  17. </bean>
  18. <!-- composite destination 供生产者使用 ,多个Queue和多个Topic -->
  19. <bean id="destinationProducer" class="org.apache.activemq.command.ActiveMQQueue">
  20. <constructor-arg index="0"
  21. value="FOO.1,FOO.2,FOO.3,FOO.4,topic://NOTIFY.FOO.D,topic://NOTIFY.FOO.E,topic://NOTIFY.FOO.F"></constructor-arg>
  22. </bean>
  23. <bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
  24. <property name="connectionFactory" ref="connectionFactory"></property>
  25. <property name="defaultDestination" ref="destinationProducer"></property>
  26. <property name="receiveTimeout" value="600"></property>
  27. </bean>
  28. <!-- 消息监听接口 -->
  29. <bean id="jmsMessageListener" class="com.ll.compositeDestination.JmsMessageListener">
  30. </bean>
  31. <!-- 消息侦听器容器,监听destination -->
  32. <bean id="consumer"
  33. class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  34. <property name="connectionFactory" ref="connectionFactory" />
  35. <property name="destination" ref="destination" />
  36. <property name="messageListener" ref="jmsMessageListener" />
  37. </bean>
  38. <!-- 消息侦听器容器,监听destination2 -->
  39. <bean id="consumer2"
  40. class="org.springframework.jms.listener.DefaultMessageListenerContainer">
  41. <property name="connectionFactory" ref="connectionFactory" />
  42. <property name="destination" ref="destination2" />
  43. <property name="messageListener" ref="jmsMessageListener" />
  44. </bean>
  45. </beans>


运行结果:


从上面两张图可以看出,发送到多个Queue中的消息全部被消费了,但是发送到多个Topic中的消息,
有且只有一个Topic的消息被消费了,其他的消息都没有被消费,为什么??
个人理解:
因为是同时发送到多个Queue和Topic中的(注意是同时,相同时刻),而消费者采用异步接收方式,
当所有消息都到达时,onMessage函数处理不过来,最多只能处理一个。
之所以Queue全部被消费了,而Topic只有1个被消费,是因为没有立即被消费的Queue消息,
会一直保存在MQ服务器(Queue消息:生产者和消费者没有时间依赖性),而Topic消息:生产者和消费者有时间依赖性,
没有被及时消费掉的消息,就再也没有机会消费了。


【ActiveMQ入门-11】ActiveMQ学习-compositeDestination的更多相关文章

  1. ActiveMQ入门之四--ActiveMQ持久化方式

    消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是同时在线或者消息中心在发送者发送消息后宕机了,在消息中心重新启动后仍然可以将消息发送出去,如果把这种持久化和 ...

  2. ActiveMQ 入门和与 Spring 整合

    ActiveMQ 入门演示 activemq 依赖 <dependency> <groupId>org.apache.activemq</groupId> < ...

  3. Dubbo入门到精通学习笔记(八):ActiveMQ的安装与使用(单节点)、Redis的安装与使用(单节点)、FastDFS分布式文件系统的安装与使用(单节点)

    文章目录 ActiveMQ的安装与使用(单节点) 安装(单节点) 使用 目录结构 edu-common-parent edu-demo-mqproducer edu-demo-mqconsumer 测 ...

  4. ActiveMQ学习总结(2)——ActiveMQ入门实例教程

    1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 2.运行ActiveMQ 解压缩apache-activemq-5.5.1-bin.zip,然后双击a ...

  5. Dubbo入门到精通学习笔记(十四):ActiveMQ集群的安装、配置、高可用测试,ActiveMQ高可用+负载均衡集群的安装、配置、高可用测试

    文章目录 ActiveMQ 高可用集群安装.配置.高可用测试( ZooKeeper + LevelDB) ActiveMQ高可用+负载均衡集群的安装.配置.高可用测试 准备 正式开始 ActiveMQ ...

  6. 【ActiveMQ入门-5】ActiveMQ学习-消息持久性

    ActiveMQ中的消息持久性     ActiveMQ很好的支持了消息的持久性(Persistence).消息持久性对于可靠消息传递来说应该是一种比较好的方法,有了消息持久化,即使发送者和接受者不是 ...

  7. Java消息中间件入门笔记 - ActiveMQ篇

    入门 消息中间件带来的好处: 1)解耦:系统解耦 2)异步:异步执行 3)横向扩展 4)安全可靠 5)顺序保证 栗子: 通过服务调用让其它系统感知事件发生 系统之间高耦合 程序执行效率低 通过消息中间 ...

  8. 消息中间件-activemq入门(二)

    上一节我们了解了JMS规范并且知道了JMS规范的良好实现者-activemq.今天我们就去了解一下activemq的使用.另外我们应该抱着目的去学习,别忘了我们为什么要使用消息中间件:解耦系统之间的联 ...

  9. ActiveMQ入门实例

    1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 2.运行ActiveMQ 解压缩apache-activemq-5.5.1-bin.zip,然后双击a ...

随机推荐

  1. SqlServer中的merge操作(转载)

    SqlServer中的merge操作(转载)   今天在一个存储过程中看见了merge这个关键字,第一个想法是,这个是配置管理中的概念吗,把相邻两次的更改合并到一起.后来在technet上搜索发现别有 ...

  2. The "Double-Checked Locking is Broken" Declaration

    双重检查锁定在延迟初始化的单例模式中见得比较多(单例模式实现方式很多,这里为说明双重检查锁定问题,只选取这一种方式),先来看一个版本: public class Singleton { private ...

  3. C标准中一些预定义的宏,如__FILE__,__func__等

    C标准中一些预定义的宏 C标准中指定了一些预定义的宏,对于编程经常会用到.下面这个表中就是一些常常用到的预定义宏. 宏 意义 __DATE__ 进行预处理的日期(“Mmm dd yyyy”形式的字符串 ...

  4. Apache 子项目 概述

    apache HTTP Server--------Web服务器(多用于静态网页,有负载均衡效果,可承受每天数百万人访问).apache Abdera>>>>>>& ...

  5. 打开WORD文档出错提示

    打开WORD文档出错提示: Microsoft Office Word 遇到问题需要关闭.我们对此引起的不便表示抱歉. 您正在处理的信息有可能丢失.Microsoft Office Word 可以尝试 ...

  6. Motorola C118 PCB原理高清图

  7. Android Studio安装、配置教程全 - 安卓开发环境的配置手册

    Android Studio的安装.配置 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 一 Downloa ...

  8. Unity插件-NGUI使用教程

    Unity插件-NGUI使用教程 本文提供全流程,中文翻译.Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) 1 NGUI 一款强大的次 ...

  9. 51Nod 1079:中国剩余定理

    1079 中国剩余定理  基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 一个正整数K,给出K Mod 一些质数的结果,求符合条件的最小的K.例如,K % ...

  10. 了解 .NET 的默认 TaskScheduler 和线程池(ThreadPool)设置,避免让 Task.Run 的性能急剧降低

    .NET Framework 4.5 开始引入 Task.Run,它可以很方便的帮助我们使用 async / await 语法,同时还使用线程池来帮助我们管理线程.以至于我们编写异步代码可以像编写同步 ...