ActiveMq(三) - 发布/订阅模式

1、概念

发布/订阅模式

发布/订阅模式允许一条消息可以被多个订阅了该Topic的消息消费者接收,当一个消息生产者产生一个消息时,会把消息放入一个Topic中,然后监听在此Topic上的消息消费者都能接收到消息。

对于发布/订阅模式,应该先启动消费者,监听在Topic上,然后等待生产者向Topic里添加消息。此处启动2个消费者

2、消费者代码

``` package com.activemq.pubsub;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageListener;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTopic;

public class Consumers {
public static void main(String[] args) throws JMSException {
//通过tcp协议获取连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://server01:61616");

//通过连接工厂获取连接
Connection connection = factory.createConnection();
connection.start();//开启连接

/**
* 创建session,此处有两个参数
* 第一个布尔类型的参数表示是否开启事务
* 第二个表示消息确认签收模式,此处为自动签收
*/
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

//创建topic
Topic topic = new ActiveMQTopic("topic");

//创建消息消费者
MessageConsumer consumer1 = session.createConsumer(topic);
consumer1.setMessageListener(new MessageListener() {

public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("消费者一收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});

//创建消息消费者
MessageConsumer consumer2 = session.createConsumer(topic);
consumer2.setMessageListener(new MessageListener() {

public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
System.out.println("消费者二收到消息:" + textMessage.getText());
} catch (JMSException e) {
e.printStackTrace();
}
}
});
}
}

查看ActiveMq控制台Topics菜单页面,看到topic对应的消费者有2个,Messages Enqueued和Messages Dequeued都是0
![](https://images2018.cnblogs.com/blog/1373276/201804/1373276-20180415104635542-556711845.png)

<h1>3、生产者代码</h1>
此处生产者只发送一条消息

package com.activemq.pubsub;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.command.ActiveMQTopic;

public class Publisher {
public static void main(String[] args) throws JMSException {
//通过tcp协议获取连接工厂
ConnectionFactory factory = new ActiveMQConnectionFactory("tcp://server01:61616");

//通过连接工厂获取连接
Connection connection = factory.createConnection();
connection.start();//开启连接

/**
* 创建session,此处有两个参数
* 第一个布尔类型的参数表示是否开启事务
* 第二个表示消息确认签收模式,此处为自动签收
*/
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

//创建topic
Topic topic = new ActiveMQTopic("topic");

//创建消息生产者
MessageProducer producer = session.createProducer(topic);

//创建消息对象
Message message = session.createTextMessage("topic消息");

//生产者发送消息
producer.send(message);
}
}


生产者启动之后,可以看到Eclipse控制台输入以下信息,表明两个消费者都收到生产者发送的这一条消息了。

消费者一收到消息:topic消息
消费者二收到消息:topic消息


再看看ActiveMq控制台,发现多了一个生产者Producer的Topic,Messages Enqueued为1,而topic对应的Messages Enqueued则变成1,Messages Dequeued 为2,也就是说,同一条消息被两个消息消费者接收到了。
![](https://images2018.cnblogs.com/blog/1373276/201804/1373276-20180415105042481-1840964775.png)
posted @ 2018-04-15 11:11  风中的蜗牛  阅读(449)  评论(0)    收藏  举报