ActiveMQ入门

这篇博客介绍了ActiveMQ的基本概念,包括点对点模型和发布/订阅模型,并详细讲解了JMS公共接口。此外,还涵盖了ActiveMQ的安装启动、使用方法,特别是如何在Spring中整合ActiveMQ,以及点对点Queue和发布/订阅Topic的示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


ActiveMQ是JMS规范的一种实现

ActiveMQ的消息形式

Java消息服务应用程序结构支持两种模型:

1.点对点模型(基于队列)

每个消息只能有一个消费者。消息的生产者和消费者之间没有时间上的相关性。可以由多个发送者,但只能被一个消费者消费。

  • 一个消息只能被一个接受者接受一次
  • 生产者把消息发送到队列中(Queue),这个队列可以理解为电视机频道(channel)
  • 在这个消息中间件上有多个这样的channel
  • 接受者无需订阅,当接受者未接受到消息时就会处于阻塞状态

2. 发布者/订阅者模型(基于主题的)

每个消息可以有多个消费者。生产者和消费者之间有时间上的相关性。订阅一个主题的消费者只能消费自它订阅之后发布的消息。

  • 允许多个接受者,类似于广播的方式
  • 生产者将消息发送到主题上(Topic)
  • 接受者必须先订阅

注:持久化订阅者:特殊的消费者,告诉主题,我一直订阅着,即使网络断开,消息服务器也记住所有持久化订阅者,如果有新消息,也会知道必定有人回来消费。

关于持久化订阅者和持久化消息的概念

JMS公共接口

JMS 公共点对点域发布/订阅域
ConnectionFactoryQueueConnectionFactoryTopicConnectionFactory
ConnectionQueueConnectionTopicConnection
DestinationQueueTopic
SessionQueueSessionTopicSession
MessageProducerQueueSenderTopicPublisher
MessageConsumerQueueReceiverTopicSubscriber
  • ConnectionFactory:连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的ActiveMQConnectionFactory。
  • Connection:JMS Connection封装了JMS 客户端到JMS Provider 的连接与JMS提供者之间的一个虚拟的连接。
  • Destination:消息的目的地,是用来指定生产的消息的目标和它消费的消息的来源的对象。
  • Session: JMS Session是生产和消费消息的一个单线程上下文。会话用于创建消息的生产者(producer),消费者(consumer),消息(message)等,会话,是一个事务性的上下文。消息的生产和消费不能包含在同一个事务中。
  • MessageProducer:由Session 对象创建的用来发送消息的对象
  • MessageConsumer:由Session 对象创建的用来发送消息的对象

JMS定义了五种不同的消息正文格式,以及调用的消息类型,允许你发送并接收以一些不同形式的数据,提供现有消息格式的一些级别的兼容性。

  • StreamMessage – Java原始值的数据流
  • MapMessage–一套名称-值对
  • TextMessage–一个字符串对象
  • ObjectMessage–一个序列化的 Java对象
  • BytesMessage–一个字节的数据流

ActiveMQ安装启动访问

安装

  • 主机安装JDK
  • ActiveMQ部署在一个Jetty容器中直接解压即可

进入apache-activemq-5.12.0/bin

  • 启动:./activemq start
  • 关闭:./activemq stop
  • 查看:./activemq status

访问Broker

  • http://IP:8161/admin
  • 输入 用户:admin,密码:admin

503错误解决,把主机名添加到hosts中

ActiveMQ的使用

添加pom依赖

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

点对点Queue

生产者Producer

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.Test;

public class QueueProducerTest {

	@Test
	public void testQueueProducer() throws Exception {
		// 1. 创建连接工厂对象ConnectionFactory,需要指定ip及端口号
		// 参数brokerURL即服务器的ip加端口号
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.110.129:61616");
		// 2. 使用ConnectionFactory对象创建connection对象
		Connection connection = connectionFactory.createConnection();
		
		// 3. 开启连接
		connection.start();
		
		// 4. 创建Session对象
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		
		// 5. 使用Session创建一个Destination对象,此处创建Queue即队列
		Queue queue = session.createQueue("test-queue");
		
		// 6. 创建一个Producer
		MessageProducer messageProducer = session.createProducer(queue);
		
		// 7.创建一个Message对象
		TextMessage textMessage = session.createTextMessage("This is my first point to point queue message!");
		
		// 8.使用Producer发送消息
		messageProducer.send(textMessage);
		
		// 9.关闭资源
		messageProducer.close();
		session.close();
		connection.close();
	}
}

消费者Consumer

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.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.Test;

public class QueueComsumerTest {

	@Test
	public void testQueueComsumer() throws Exception {
		// 1.创建连接工厂ConnectionFactory
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.110.129:61616");
		// 2.创建连接
		Connection connection = connectionFactory.createConnection();
		
		// 3.启动
		connection.start();
		
		// 4.创建session
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		
		// 5.创建destination,注意名称要与生产端一致
		Queue queue = session.createQueue("test-queue");
		
		// 6.创建消费者
		MessageConsumer comsumer = session.createConsumer(queue);
		
		// 7.接受消息,这里是对某一个Destination做监听,即test-queue
		comsumer.setMessageListener(new MessageListener() {
			
			@Override
			public void onMessage(Message message) {
				
				if(message instanceof TextMessage) {
					TextMessage text = (TextMessage) message;
					try {
						String myMsg = text.getText();
						// 8.打印消息This is my first point to point queue message!
						System.out.println(myMsg);
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
				
			}
			
		});
		
		// 9.等待键盘输入,不让进程退出
		System.in.read();
		
		// 10.关闭资源
		comsumer.close();
		session.close();
		connection.close();
	}
}

演示:

  1. 运行Producer
    在这里插入图片描述
  2. 运行Consumer
    在这里插入图片描述
    在这里插入图片描述

发布于订阅Topic

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.junit.Test;

public class TopicProducerTest {
	@Test
	public void testQueueProducer() throws Exception {
		// 1. 创建连接工厂对象ConnectionFactory,需要指定ip及端口号
		// 参数brokerURL即服务器的ip加端口号
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.110.129:61616");
		// 2. 使用ConnectionFactory对象创建connection对象
		Connection connection = connectionFactory.createConnection();
		
		// 3. 开启连接
		connection.start();
		
		// 4. 创建Session对象
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		
		// 5. 使用Session创建一个Destination对象,此处创建话题Topic
		Topic topic = session.createTopic("test-topic");
		
		// 6. 创建一个Producer
		MessageProducer messageProducer = session.createProducer(topic);
		
		// 7.创建一个Message对象
		TextMessage textMessage = session.createTextMessage("This is my first topic message!");
		
		// 8.使用Producer发送消息
		messageProducer.send(textMessage);
		
		// 9.关闭资源
		messageProducer.close();
		session.close();
		connection.close();
	}
}

消费者Consumer

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.junit.Test;

public class TopicComsumerTest {
	@Test
	public void testQueueComsumer() throws Exception {
		// 1.创建连接工厂ConnectionFactory
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				"tcp://192.168.110.129:61616");
		// 2.创建连接
		Connection connection = connectionFactory.createConnection();
		
		// 3.启动
		connection.start();
		
		// 4.创建session
		Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
		
		// 5.创建destination,注意名称要与生产端一致
		Topic topic = session.createTopic("test-topic");
		
		// 6.创建消费者
		MessageConsumer comsumer = session.createConsumer(topic);
		
		// 7.接受消息,这里是对某一个Destination做监听,即test-topic
		comsumer.setMessageListener(new MessageListener() {
			
			@Override
			public void onMessage(Message message) {
				
				if(message instanceof TextMessage) {
					TextMessage text = (TextMessage) message;
					try {
						String myMsg = text.getText();
						// 8.打印消息This is my first point to point queue message!
						System.out.println(myMsg);
					} catch (JMSException e) {
						e.printStackTrace();
					}
				}
				
			}
			
		});
		System.out.println("消费者01...");
		// 9.等待键盘输入,不让进程退出
		System.in.read();
		
		// 10.关闭资源
		comsumer.close();
		session.close();
		connection.close();
	}
}

演示:
topic是与时间相关的,要先启动消费者,再启动生产者,不然演示不成功。这里不讨论持久化订阅者。

  1. 启动消费者01
    在这里插入图片描述
    启动消费者02(只需要改一下代码)
    在这里插入图片描述
    查看activemq
    在这里插入图片描述
  2. 启动生产者
    查看消费者01
    在这里插入图片描述
    查看消费者02
    在这里插入图片描述
    查看activemq
    在这里插入图片描述

Spring整合ActiveMQ

生产者

测试类

import javax.annotation.Resource;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.jms.Topic;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-activemq-send.xml")
public class ActiveMQProducer {
	
	@Resource(name="jmsTemplate")
	private JmsTemplate jmsTemplate;
	
	@Resource(name="queueDestination")
	private Queue queue;
	
	@Resource(name="topicDestination")
	private Topic topic; 
	
	@Resource(name="topicDestination1")
	private Topic topic1; 
	
	@Test
	public void testProducer() {
		testSendQueue();
		testSendTopic();
		testSendTopic1();
	}
	
	@Test
	public void testSendQueue() {
		jmsTemplate.send(queue, new MessageCreator() {
			
			@Override
			public Message createMessage(Session session) throws JMSException {
				// 消息体根据业务变化
				TextMessage message = session.createTextMessage("This is my first queue with spring 支持中文!");
				return message;
			}
			
		});
	}
	
	@Test
	public void testSendTopic() {
		
		jmsTemplate.send(topic, new MessageCreator() {
			
			@Override
			public Message createMessage(Session session) throws JMSException {
				// 消息体根据业务变化
				TextMessage message = session.createTextMessage("This is my first topic with spring 支持中文!");
				return message;
			}
			
		});
		
	}
	
	@Test
	public void testSendTopic1() {
		
		jmsTemplate.send(topic1, new MessageCreator() {
			
			@Override
			public Message createMessage(Session session) throws JMSException {
				// 消息体根据业务变化
				TextMessage message = session.createTextMessage("This is my first topic1 with spring 支持中文!");
				return message;
			}
			
		});
		
	}
}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	<!-- 真正的可以产生connection的connectionFactory,有JMS服务商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://192.168.110.129:61616"/>
	</bean>
	<!-- spring用于管理真正connectionFactory的connectionFactory -->
	<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
	</bean>
	
	<!-- 发送 -->
	<!-- spring提供的JMS工具类 -->
	<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="connectionFactory"/>
	</bean>
	<!-- 配置消息的Destination对象 -->
	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg name="name" value="myQueue"></constructor-arg>
	</bean>
	<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg name="name" value="myTopic"></constructor-arg>
	</bean>
		<bean id="topicDestination1" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg name="name" value="myTopic1"></constructor-arg>
	</bean>
</beans>

消费者

测试类(加载spring配置,阻塞即可)

import java.io.IOException;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext-activemq-receive.xml")
public class ActiveMQComsumer {
	
	@Test
	public void testComsumer() throws IOException {
		System.in.read();
	}
}

监听器

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class MyQueueMessageListener implements MessageListener {
	@Override
	public void onMessage(Message message) {
		if(message instanceof TextMessage) {
			try {
				TextMessage text = (TextMessage) message;
				String msg = text.getText();
				System.out.println(msg);
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
	}
}
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class MyMessageListener implements MessageListener {
	@Override
	public void onMessage(Message message) {
		if(message instanceof TextMessage) {
			try {
				TextMessage text = (TextMessage) message;
				String msg = text.getText();
				System.out.println(msg);
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
	}
}
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class MyMessageListener1 implements MessageListener {
	@Override
	public void onMessage(Message message) {
		if(message instanceof TextMessage) {
			try {
				TextMessage text = (TextMessage) message;
				String msg = text.getText();
				System.out.println(msg);
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}
	}
}

xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
	
	<!-- 真正的可以产生connection的connectionFactory,有JMS服务商提供 -->
	<bean id="targetConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
		<property name="brokerURL" value="tcp://192.168.110.129:61616"/>
	</bean>
	<!-- spring用于管理真正connectionFactory的connectionFactory -->
	<bean id="connectionFactory" class="org.springframework.jms.connection.SingleConnectionFactory">
		<property name="targetConnectionFactory" ref="targetConnectionFactory"/>
	</bean>
	
	<!-- 配置消息的Destination对象 -->
	<bean id="queueDestination" class="org.apache.activemq.command.ActiveMQQueue">
		<constructor-arg name="name" value="myQueue"></constructor-arg>
	</bean>
	<bean id="topicDestination" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg name="name" value="myTopic"></constructor-arg>
	</bean>
	<bean id="topicDestination1" class="org.apache.activemq.command.ActiveMQTopic">
		<constructor-arg name="name" value="myTopic1"></constructor-arg>
	</bean>
	
	<!-- 接收 -->
	<!-- 配置监听器 -->
	<bean id="myQueueListener" class="com.yp.activemqSpring.MyQueueMessageListener"/>
	<bean id="myMessageListener" class="com.yp.activemqSpring.MyMessageListener"/>
	<bean id="myMessageListener1" class="com.yp.activemqSpring.MyMessageListener1"/>
	<!-- 消息监听容器 -->
	<bean id="queueListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="queueDestination" />
		<property name="messageListener" ref="myQueueListener" />
	</bean>
	<bean id="topicListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="topicDestination" />
		<property name="messageListener" ref="myMessageListener" />
	</bean>
	<bean id="topicListenerContainer1" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="destination" ref="topicDestination1" />
		<property name="messageListener" ref="myMessageListener1" />
	</bean>
</beans>

演示

启动消费者
在这里插入图片描述
在这里插入图片描述
启动生产者
在这里插入图片描述
在这里插入图片描述

要开始使用ActiveMQ,您需要按照以下步骤进行安装和配置: 1. 首先,您可以从ActiveMQ的官方网站()下载安装包。您可以在此链接中找到最新的版本。 2. 下载完成后,您可以使用wget命令()将下载的安装包传输到您的Linux系统中。 3. 解压缩安装包,您可以使用tar命令()执行:tar -xzvf apache-activemq-5.14.0-bin.tar.gz。这将解压缩安装包到当前目录。 4. 进入解压缩后的bin目录,并启动ActiveMQ。您可以使用命令:./activemq start。这将启动ActiveMQ,并将其作为后台进程运行。 5. 您可以使用命令ps -ef|grep activemq检查ActiveMQ是否成功启动()。 一旦ActiveMQ成功安装并启动,您可以使用Java代码与其进行交互。以下是一些基本操作: 1. 导入ActiveMQ的依赖项。您可以在您的Java项目的pom.xml文件中添加以下依赖项(): <dependency> <groupId>org.apache.activemq</groupId> <artifactId>activemq-all</artifactId> <version>5.15.9</version> </dependency> 2. 创建队列。您可以使用ActiveMQ的API来创建一个队列,以便在消息传递中使用。 3. 创建主题。类似于队列,您也可以使用ActiveMQ的API来创建一个主题,用于发布和订阅消息。 这些是使用ActiveMQ的一些基本入门步骤。您可以通过阅读ActiveMQ的官方文档和API文档来深入了解更多功能和使用方法。希望这可以帮助您开始使用ActiveMQ。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [ActiveMQ入门](https://blog.youkuaiyun.com/qq_34195507/article/details/101022427)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [ActiveMQ入门学习](https://blog.youkuaiyun.com/dpf373521/article/details/101024790)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值