一、简介

发布者/订阅者模型支持一个特定的消息主题发布消息。0或N个订阅者可能对接收来自特定主题的消息感兴趣。在这种模型下,发布者和订阅者彼此不知道对方。这种模型可以概括为:

☆ 多个消费者(主题订阅者)可以获得相同的消息

☆在发布者和订阅者之间存在时间依赖性。发布者需要建立一个订阅(subscription),以便客户能够订阅。订阅者必须保持持续的活动状态才可以接收消息。如果发布者发布消息时,订阅者处于非活动状态下,则订阅者无法获取消息,即使重新活动时,也无法获取刚刚发布的消息。

☆ 经常在一个主题消息需要多个消费者消费的情况下使用

mysql 订阅发布 mysql消息订阅与发布_System

注意:发布订阅模式和点对点的使用基本相同,此处不再过多陈述。只要把

Destination destination = session.createQueue("test-Queue");

换成下面的,就是发布订阅主题模式:

Topic topic = session.createTopic("test-Topic");

二、代码简介

package com.hanchao.mq;
import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.Test;
import javax.jms.*;
/**
* 发布订阅消息模型测试
*
* @author liweihan
* @time 2018-01-27 12:23
*/
public class AcTiveMQTest2 {
/**
* @author liweihan
* @description 生产消息到主题
* @throws Exception
*/
@Test
public void sendMessageToTopic() throws Exception {
//1.创建ConnectionFactory
String brokerUrl = "tcp://localhost:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
//2.创建连接 并开启
Connection connection = connectionFactory.createConnection();
connection.start();
//3.创建Session
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//4.创建消息目的地-主题
Topic topic = session.createTopic("test-Topic");
//5.创建生产者
MessageProducer producer = session.createProducer(topic);
//6.创建并发送消息
for (int i = 4; i <= 9; i++) {
TextMessage textMessage = session.createTextMessage("Hello,MQ-"+i);
producer.send(textMessage,DeliveryMode.PERSISTENT,i,0);
}
//7.释放资源
producer.close();
session.close();
connection.close();
}
/**
* @author liweihan
* @description 主题消费消息1:主题发布消息时,
* 此消费者必须活着才能接收到主题发布的消息。
*
* 先于生产者启动才可以测试成功!
*/
@Test
public void consumerMessageFromTopic() throws Exception{
//1.创建ConnectionFactory
String brokerUrl = "tcp://localhost:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
//2.创建连接 并开启
Connection connection = connectionFactory.createConnection();
connection.start();
//3.创建Session
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//4.创建消息目的地
Topic topic = session.createTopic("test-Topic");
//5.创建消费者
MessageConsumer consumer = session.createConsumer(topic);
//6.消费消息:监听队列中的消息,如果有新的消息,则会执行onMessage()方法
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
String text = textMessage.getText();
System.out.println(" consumer 1 >>> : " + text);
} catch (JMSException e) {
//对异常不做处理,直接上抛
throw new RuntimeException(e);
}
}
});
/**
* System.in.read();就是为了不让程序退出,可以打印消息!
* 不是程序需要的!
*/
System.in.read();
//释放资源
consumer.close();
session.close();
connection.close();
}
/**
* @author liweihan
* @description 消费消息2:主题发布消息时,
* 此消费者必须活着才能接收到主题发布的消息。
*
* 先于生产者启动才可以测试成功!
*/
@Test
public void consumerMessageFromTopic2() throws Exception{
//1.创建ConnectionFactory
String brokerUrl = "tcp://localhost:61616";
ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl);
//2.创建连接 并开启
Connection connection = connectionFactory.createConnection();
connection.start();
//3.创建Session
Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
//4.创建消息目的地
Topic topic = session.createTopic("test-Topic");
//5.创建消费者
MessageConsumer consumer = session.createConsumer(topic);
//6.消费消息:监听队列中的消息,如果有新的消息,则会执行onMessage()方法
consumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
TextMessage textMessage = (TextMessage)message;
try {
String text = textMessage.getText();
System.out.println(" consumer 2 >>> : " + text);
} catch (JMSException e) {
//对异常不做处理,直接上抛
throw new RuntimeException(e);
}
}
});
/**
* System.in.read();就是为了不让程序退出,可以打印消息!
* 不是程序需要的!
*/
System.in.read();
//释放资源
consumer.close();
session.close();
connection.close();
}
}