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  风中的蜗牛  阅读(431)  评论(0编辑  收藏  举报