一、概念

  • 发布者/订阅者模型支持向一个特定的消息主题发布消息。0或多个订阅者可能对接收来自特定消息主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方。这种模式好比是匿名公告板。这种模式被概括为:多个消费者可以获得消息
  • 在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription),以便客户能够订阅。订阅者必须保持持续的活动状态以接收消息,除非订阅者建立了持久的订阅。在那种情况下,在订阅者未连接时发布的消息将在订阅者重新连接时重新发布。

二、案例

  2.1  消息生产者-消息发布者

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; /**
* 消息生产者
* @author Administrator
*
*/
public class JMSProducer { private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名
private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码
private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址
private static final int SENDNUM=10; // 发送的消息数量 public static void main(String[] args) { ConnectionFactory connectionFactory; // 连接工厂
Connection connection = null; // 连接
Session session; // 会话 接受或者发送消息的线程
Destination destination; // 消息的目的地
MessageProducer messageProducer; // 消息生产者 // 实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(JMSProducer.USERNAME, JMSProducer.PASSWORD, JMSProducer.BROKEURL); try {
connection=connectionFactory.createConnection(); // 通过连接工厂获取连接
connection.start(); // 启动连接
session=connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE); // 创建Session
// destination=session.createQueue("FirstQueue1"); // 创建消息队列
destination=session.createTopic("firstTopic");
messageProducer=session.createProducer(destination); // 创建消息生产者
sendMessage(session, messageProducer); // 发送消息
session.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
if(connection!=null){
try {
connection.close();
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
} /**
* 发送消息
* @param session
* @param messageProducer
* @throws Exception
*/
public static void sendMessage(Session session,MessageProducer messageProducer)throws Exception{
for(int i=0;i<JMSProducer.SENDNUM;i++){
TextMessage message=session.createTextMessage("ActiveMQ 发布的消息"+i);
System.out.println("发送消息:"+"ActiveMQ 发布的消息"+i);
messageProducer.send(message);
}
}
}

  2.2  消息消费者-消息订阅者一

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public class JMSConsumer {
private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名
private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码
private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址 public static void main(String[] args) { ConnectionFactory connectionFactory; // 连接工厂
Connection connection = null; // 连接
Session session; // 会话 接受或者发送消息的线程
Destination destination; // 消息的目的地
MessageConsumer consumer; //创建消费者 // 实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(JMSConsumer.USERNAME, JMSConsumer.PASSWORD, JMSConsumer.BROKEURL); try {
connection=connectionFactory.createConnection(); // 通过连接工厂获取连接
connection.start(); // 启动连接
/**
* 这里的最好使用Boolean.FALSE,如果是用true则必须commit才能生效,且http://127.0.0.1:8161/admin管理页面才会更新消息队列的变化情况。
*/
session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Session
// destination=session.createQueue("FirstQueue1"); // 创建消息队列
destination=session.createTopic("firstTopic");
consumer=session.createConsumer(destination);
consumer.setMessageListener(new MyListener()); // 注册消息监听
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
  • 监听器1

package com.shyroke.firstActiveMQ2;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; public class MyListener implements MessageListener { public void onMessage(Message message) {
try {
System.out.println("订阅者一收到的消息:"+((TextMessage)message).getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }

  2.3  消息消费者-消息订阅者二

package com.shyroke.firstActiveMQ2;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage; import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory; public class JMSConsumer2 {
private static final String USERNAME=ActiveMQConnection.DEFAULT_USER; // 默认的连接用户名
private static final String PASSWORD=ActiveMQConnection.DEFAULT_PASSWORD; // 默认的连接密码
private static final String BROKEURL=ActiveMQConnection.DEFAULT_BROKER_URL; // 默认的连接地址 public static void main(String[] args) { ConnectionFactory connectionFactory; // 连接工厂
Connection connection = null; // 连接
Session session; // 会话 接受或者发送消息的线程
Destination destination; // 消息的目的地
MessageConsumer consumer; //创建消费者 // 实例化连接工厂
connectionFactory=new ActiveMQConnectionFactory(JMSConsumer2.USERNAME, JMSConsumer2.PASSWORD, JMSConsumer2.BROKEURL); try {
connection=connectionFactory.createConnection(); // 通过连接工厂获取连接
connection.start(); // 启动连接
/**
* 这里的最好使用Boolean.FALSE,如果是用true则必须commit才能生效,且http://127.0.0.1:8161/admin管理页面才会更新消息队列的变化情况。
*/
session=connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE); // 创建Session
// destination=session.createQueue("FirstQueue1"); // 创建消息队列
destination=session.createTopic("firstTopic");
consumer=session.createConsumer(destination);
consumer.setMessageListener(new MyListener2()); // 注册消息监听
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
  • 监听器2

package com.shyroke.firstActiveMQ2;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage; public class MyListener implements MessageListener { public void onMessage(Message message) {
try {
System.out.println("订阅者一收到的消息:"+((TextMessage)message).getText());
} catch (JMSException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }
  • 测试以及结果

发布- 订阅消息模式首先必须订阅者先订阅服务,然后发布者再发布消息,最后订阅者受到服务消息。

所以本章我们先执行消息订阅者一和消息订阅者二的代码然后查看ActiveMQ的管理界面:

如图可见,订阅者已经注册成功,然后再发布者发布消息:

(三)ActiveMQ之发布- 订阅消息模式实现的更多相关文章

  1. ActiveMQ发布-订阅消息模式

    一.订阅杂志我们很多人都订过杂志,其过程很简单.只要告诉邮局我们所要订的杂志名.投递的地址,付了钱就OK.出版社定期会将出版的杂志交给邮局,邮局会根据订阅的列表,将杂志送达消费者手中.这样我们就可以看 ...

  2. ActiveMQ发布-订阅消息模式(同点对点模式的区别)

    点对点与发布订阅最初是由JMS定义的.这两种模式主要区别或解决的问题就是发送到队列的消息能否重复消费(多订阅) 点对点: 消息生产者生产消息发送到queue中,然后消息消费者从queue中取出并且消费 ...

  3. NetMQ(三): 发布订阅模式 Publisher-Subscriber

    ZeroMQ系列 之NetMQ 一:zeromq简介 二:NetMQ 请求响应模式 Request-Reply 三:NetMQ 发布订阅模式 Publisher-Subscriber 四:NetMQ ...

  4. “一切都是消息”--MSF(消息服务框架)之【发布-订阅】模式

    在上一篇,“一切都是消息”--MSF(消息服务框架)之[请求-响应]模式 ,我们演示了MSF实现简单的请求-响应模式的示例,今天来看看如何实现[发布-订阅]模式.简单来说,该模式的工作过程是: 客户端 ...

  5. “一切都是消息”--iMSF(即时消息服务框架)之【发布-订阅】模式

    MSF的名字是 Message Service Framework 的简称,由于目前框架主要功能在于处理即时(immediately)消息,所以iMSF就是 immediately Message S ...

  6. 【ActiveMQ】- 发布/订阅模式

    publish/subscribe 特点:A发送的消息可以被所有监听A的对象的接收,就好比学校的广播,所有的学生都可以收听校园广播信息. 消息生产者: package com.zhiwei.advan ...

  7. 分布式发布订阅消息系统 Kafka 架构设计[转]

    分布式发布订阅消息系统 Kafka 架构设计 转自:http://www.oschina.net/translate/kafka-design 我们为什么要搭建该系统 Kafka是一个消息系统,原本开 ...

  8. Kafka(分布式发布-订阅消息系统)工作流程说明

    Kafka系统架构Apache Kafka是分布式发布-订阅消息系统.它最初由LinkedIn公司开发,之后成为Apache项目的一部分.Kafka是一种快速.可扩展的.设计内在就是分布式的,分区的和 ...

  9. kafka 基础知识梳理-kafka是一种高吞吐量的分布式发布订阅消息系统

    一.kafka 简介 今社会各种应用系统诸如商业.社交.搜索.浏览等像信息工厂一样不断的生产出各种信息,在大数据时代,我们面临如下几个挑战: 如何收集这些巨大的信息 如何分析它 如何及时做到如上两点 ...

随机推荐

  1. Link static data in sql source control

    You can link data that doesn't change very often to SQL Source Control. This lets you commit data ch ...

  2. 【Canvas】绘制几何级数Geometric series曲线 y=1+1/2+1/4+1/8+1/16+1/32+1/64+....

    相关资料:https://baike.baidu.com/item/%E5%87%A0%E4%BD%95%E7%BA%A7%E6%95%B0/112584?fr=aladdin 图线: 代码: < ...

  3. (32位汇编 五)mov/add/sub/and/or/xor/not

    本文链接:https://blog.csdn.net/pl20140910/article/details/78227133说明符号 说明r 通用寄存器m 代表内存imm 代表立即数r8 代表8位通用 ...

  4. BitmapFactory之Options

    package com.loaderman.customviewdemo; import android.app.Activity; import android.graphics.Bitmap; i ...

  5. 算法习题---4-6莫尔斯电码(UVa508)

    一:题目 A-Z0-9分别对应一些莫尔斯电码字符串 A .- B -... C -.-. D -.. E . F ..-. G --. H .... I .. J .--- K -.- L .-.. ...

  6. Github排名靠前的iOS库

    //iOS第三方开源库的吐槽和备忘 http://blog.ibireme.com/2013/09/23/ios-third-party-libs/#more-41361 //整理了一份Github上 ...

  7. iOS的推送证书过期的处理

    1.删除MAC上钥匙串访问中对应的推送证书.<根据过期日期看> 2.登录苹果开发者后台,revoke删除已过期推送证书(貌似会自己消失不用删除,具体记不清了...),然后为对应App ID ...

  8. c#webservice的简单示例

    webservice.就概念上来说,可能比较复杂,不过我们可以有个宏观的了解:webservice就是个对外的接口,里面有 函数可供外部客户调用(注意:里面同样有客户不可调用的函数).假若我们是服务端 ...

  9. Jenkins备份插件backup

    这个插件可以备份Jenkins的JENKINS_HOME目录,并恢复,但是版本太旧了. 有一些其他插件可以定时备份,搜索Backup https://www.cnblogs.com/cxwblog/p ...

  10. pip3快速下载paddle

    安装百度的paddle paddle时很慢,后来采用国内的源,速度嗖嗖滴 pip3 install -U paddlepaddle -i https://pypi.douban.com/simple/ ...