ActiveMQ之队列和主题

ActiveMQ的使用分为两种,一种是嵌入式,即把ActiveMQ作为内嵌的JMS provider集成到Tomcat或其他Web服务器中;另一种是独立部署,即ActiveMQ单独部署,独立运行,通过ActiveMQ提供的API进行进程外访问。为了更有利于业务的解耦和工程部署结构的分离;也有利于对ActiveMQ进行配置定制和优化,可以采用独立部署的方式使用ActiveMQ。

JMS 支持两种截然不同的消息传送模型:PTP(即点对点模型)和Pub/Sub(即发布/订阅模型),分别称作:PTP Domain 和Pub/Sub Domain。
PTP(使用Queue即队列目标)     消息从一个生产者传送至一个消费者。在此传送模型中,目标是一个队列。消息首先被传送至队列目标,然后根据队列传送策略,从该队列将消息传送至向此队列进行注册的某一个消费者,一次只传送一条消息。可以向队列目标发送消息的生产者的数量没有限制,但每条消息只能发送至、并由一个消费者成功使用。如果没有已经向队列目标注册的消费者,队列将保留它收到的消息,并在某个消费者向该队列进行注册时将消息传送给该消费者。
Pub/Sub(使用Topic即主题目标)     消息从一个生产者传送至任意数量的消费者。在此传送模型中,目标是一个主题。消息首先被传送至主题目标,然后传送至所有已订阅此主题的活动消费者。可以向主题目标发送消息的生产者的数量没有限制,并且每个消息可以发送至任意数量的订阅消费者。主题目标也支持持久订阅的概念。持久订阅表示消费者已向主题目标进行注册,但在消息传送时此消费者可以处于非活动状态。当此消费者再次处于活动状态时,它将接收此信息。如果没有已经向主题目标注册的消费者,主题不保留其接收到的消息,除非有非活动消费者注册了持久订阅。

下面我们通过代码演示ActiveMQ对以上2种消息模式的使用方式。

引入activeMQ jar包

<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-all</artifactId>
			<version>5.8.0</version>
		</dependency>

一、队列模型

在点对点的传输方式中,消息数据被持久化,每条消息都能被消费,没有监听QUEUE地址也能被消费,数据不会丢失,一对一的发布接受策略,保证数据完整。

生产者:

package cn.slimsmart.activemq.demo.queue;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.DeliveryMode;
import javax.jms.Destination;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

//队列
public class Producer {

	public static void main(String[] args) throws Exception {
		// 连接工厂,JMS 用它创建连接
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,
				"tcp://192.168.18.43:61616");
		// 构造从工厂得到连接对象
		Connection connection = connectionFactory.createConnection();
		// 启动
		connection.start();
		// 获取操作连接 一个发送或接收消息的线程
		Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
		// 获取session注意参数值slimsmart.queue是一个queue
		Destination destination = session.createQueue("slimsmart.queue.test");
		// 得到消息生成者【发送者】
		MessageProducer producer = session.createProducer(destination);
		// 设置持久化,
		producer.setDeliveryMode(DeliveryMode.PERSISTENT);
		// 构造消息,并发送
		sendMessage(session, producer);
		//提交
		session.commit();
		session.close();
		connection.close();
	}

	public static void sendMessage(Session session, MessageProducer producer) throws Exception {
		for (int i = 1; i <= 5; i++) {
			TextMessage message = session.createTextMessage("发送的消息" + i);
			// 发送消息到目的地方
			System.out.println("发送消息:" + "发送的消息" + i);
			producer.send(message);
		}
	}

}
消费者:

package cn.slimsmart.activemq.demo.queue;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
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 org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;

public class Consumer {

	public static void main(String[] args) throws Exception {
		// 连接工厂,JMS 用它创建连接
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD,
				"tcp://192.168.18.43:61616");
		// 构造从工厂得到连接对象
		Connection connection = connectionFactory.createConnection();
		// 启动
		connection.start();
		// 获取操作连接 一个发送或接收消息的线程
		//第一个参数为true  标识开启事务,需要手工commit
		final Session session = connection.createSession(Boolean.FALSE, Session.AUTO_ACKNOWLEDGE);
		// 获取session注意参数值slimsmart.queue是一个服务器的queue,星号*匹配任意字符
		Destination destination = session.createQueue("slimsmart.queue.test");
		// 消费者,消息接收者
		MessageConsumer consumer = session.createConsumer(destination);
		consumer.setMessageListener( new MessageListener() {
			public void onMessage(Message message) {
				TextMessage textMsg = (TextMessage)message;
				try {
					System.out.println("收到消息" + textMsg.getText());
					//session.commit();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		});
		Thread.sleep(100000);
		/*
		while (true) {
            //设置接收者接收消息的时间,为了便于测试,这里设定为100s
            TextMessage message = (TextMessage) consumer.receive(100000);
            if (null != message) {
                System.out.println("收到消息" + message.getText());
            } else {
                break;
            }
        }*/
		session.close();
		connection.close();
	}
}
二、主题模型
在发布订阅消息方式中,消息是无状态的,不保证每条消息被消费,只有监听该TOPIC地址才能收到消息并消费,否则该消息将会丢失。一对多的发布接受策略,可以同时消费多个消息。

生产者:

package cn.slimsmart.activemq.demo.topic;

import javax.jms.Connection;
import javax.jms.DeliveryMode;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;

public class Producer {

	public static void main(String[] args) throws JMSException {
		// 连接到ActiveMQ服务器
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.18.43:61616");
		Connection connection = factory.createConnection();
		connection.start();
		Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
		// 创建主题
		Topic topic = session.createTopic("slimsmart.topic.test");
		MessageProducer producer = session.createProducer(topic);
		// NON_PERSISTENT 非持久化 PERSISTENT 持久化
		producer.setDeliveryMode(DeliveryMode.PERSISTENT);
		TextMessage message = session.createTextMessage();
		message.setText("topic 消息。");
		message.setStringProperty("property", "消息Property");
		// 发布主题消息
		producer.send(message);
		System.out.println("Sent message: " + message.getText());
		session.commit();
		session.close();
		connection.close();
	}
}
消费者:

package cn.slimsmart.activemq.demo.topic;

import javax.jms.Connection;
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;

public class Consumer {

	public static void main(String[] args) throws JMSException {
		// 连接到ActiveMQ服务器
		ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory("tcp://192.168.18.43:61616");
		Connection connection = factory.createConnection();
		connection.start();
		final Session session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
		// 创建主题 
		Topic topic = session.createTopic("slimsmart.topic.test");
		// 创建订阅
		MessageConsumer consumer = session.createConsumer(topic);
		consumer.setMessageListener(new MessageListener() {
			// 订阅接收方法
			public void onMessage(Message message) {
				TextMessage tm = (TextMessage) message;
				try {
					System.out.println("Received message: " + tm.getText()+":"+tm.getStringProperty("property"));
					session.commit();
				} catch (JMSException e) {
					e.printStackTrace();
				}
			}
		});
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值