(视频:尚硅谷:尚硅谷ActiveMQ教程(MQ消息中间件快速入门)_哔哩哔哩_bilibili)(其他的消息中间件也这么学)
目录
九.ActiveMQ 的消息存储 和。持久化 ---高级

一.入门概述:
1)前言:
a:在何种场景下,使用了消息中间件?
- 1.
- 2.
b:为什么要在系统里,引入消息中间件?
- 1.
- 2.
c:........
2)从生活 Case 到实际生产案例:
a:上述问题 引出产生背景:系统之间 直接调用 实际工程 落地和存在的问题
- 1.系统之间接口 耦合度高。每新增一个下游功能,都要对上游的相关接口进行改造。
- 2.面对大流量并发时,容易被冲垮。每个接口的吞吐能力有限,大流量并发时容易冲垮。
- 3.等待同步存在性能问题。
b:举例秒杀业务:
- 1.上游系统,发起下订单购买操作,就是下单一个操作。
- 2.下游系统,完成秒杀业务逻辑。(11 步操作)
1.读取订单、库存检查、库存冻结、余额检查、余额冻结、订单生成、余额扣减、库存扣减、
2.生成流水、余额解冻、库存解封。
c:需要有一种东东,能够摆平上述情况:
- 1.
- 2.
- 3.
- 4.
- 5.
3)是什么:
a:定义:
- 1.面向消息的 中间件(message-oriented middleware)MOM ,能够很好的解决以上问题。
- 2.是指 利用:高效可靠的 消息传递机制,进行与平台无关的数据交流,并 基于数据通信,来进行分布式系统的集成。
- 3.通过提供 消息传递 和 消息排队 模型,在分布式环境下提供:应用解耦、弹性伸缩、冗余存储、流量晓峰、异步通信、数据同步 等功能。
- 4.大致过程:
1.发送者把消息,发送给消息服务器,消息服务器将消息存放在若干 队列 / 主题 中。在合适的时候,消息服务器会将消息转发给接受者。
2.在这个过程中,发送 和 接收 是异步的,也就是发送无需等待,而且发送者 和 接受者 的生命周期,也没有必然的关系
3.尤其在 发布 pub / 订阅 sub 模式下,也可以完成一对多的通信,即让一个消息,有多个接受者。
b:特点:
- 1.采用异步处理模式:
1.消息发送者,可以发送一个消息 而无需等待响应。消息发送着将消息发送到一条虚拟的通道(主题 / 队列)上。
2.消息接收者,则订阅 或 监听 该通道。
3.一条信息,可能最终转发给一个 或 多个 消息接收者,这些接收者,都无需 对消息发送着做出同步回应。
4.整个过程都是异步的。
- 2.应用系统之间 解耦:
1.发送者 和 接收者,不必了解对方,只需要确认消息;
2.发送者 和 接收者 不必同时在线。
- 3.电商业务案例:
4)能干嘛:
a:应用解耦:要做到系统解耦,当新模块接进来时,可以做到代码改动最小。
b:流量削峰:设置流量缓冲池,可以让后端系统,按照自身吞吐能力进行消费,不被冲垮。
c:消息异步:强弱依赖梳理,能将非关键调用链路到操作,异步化并提升整体系统的吞吐能力。
5)去哪下:(官网)
a:ActiveMQ
6)怎么玩:
a:最主要功能:实现高可用、高性能、可伸缩、易用 和 安全 的企业级,面向消息服务的系统。
b:异步消息的消费和处理:
c:控制消息的消费顺序:
d:可以和 Spring / SpringBoot 整合,简化编码:
e:配置集群容错的 MQ 集群:
二.ActiveMQ 安装 和 控制台
1)官网下载:(ActiveMQ)
2)Linux 安装:
a:上传到:/opt/activemq/,并解压
b:普通启动:./activemq start
c:查看启动:(lsof -i:61616)(ps -ef | grep activemq)(netstat -anp|grep 61616)
d:普通关闭:./activemq stop
e:带日志的启动方式:(./activemq start > myrunmq.log)
3)ActiveMQ 控制台 访问:
a:控制台地址:( http://114.215.173.88:8161/admin )( admin / admin )
b:云服务器,jetty.xml文件,修改为:重启再次访问
<bean id="jettyPort" class="org.apache.activemq.web.WebConsolePort" init-method="start">
<!-- the default port number for the web console -->
<property name="host" value="0.0.0.0"/>
<property name="port" value="8161"/>
</bean>
4)备注:
a:采用 61616 端口,提供 JMS 服务。
b:采用 8161 端口,提供管理控制台服务。
三.Java 编码 实现 ActiveMQ 通讯
1)IDEA 新建 maven 工程:
2)POM.xml:
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>activemq-all</artifactId>
<version>5.15.9</version>
</dependency>
<dependency>
<groupId>org.apache.xbean</groupId>
<artifactId>xbean-spring</artifactId>
<version>3.16</version>
</dependency>
3)JMS 编码总体架构:(类似 JDBC)
4)粗说 目的地 Destination -> 队列 和 主题:
a:概览:
b:队列 和 主题 图解:
5)在 点对点的 消息传递域中,目的地被称为 队列(queue):上手案例

a:消息生产者:
- 1.代码:
public class MySendMessage {
public static final String ACTIVE_MQ = "tcp://114.215.173.88:61616";
public static final String QUEUE_NAME = "queue_01";
public static void main(String[] args) throws JMSException {
//1.创建 连接工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVE_MQ);
//2. 通过连接工厂,获得连接 Connection
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//3. 创建会话(事务,签收)
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4.创建目的地(具体是队列 还是 主题 topic)
Queue queue = session.createQueue(QUEUE_NAME);
//5. 创建消息生产者
MessageProducer messageProducer = session.createProducer(queue);
//6.通过使用 MessageProducer ,生产 3 条消息,发送给 mq 队列里面。
for (int i = 0; i < 3; i++) {
//7.创建消息
TextMessage textMessage = session.createTextMessage("这是第:" + i + " 条消息");
//8.通过 messageProducer 发送给 MQ
messageProducer.send(textMessage);
}
//9.关闭资源 (倒着关闭)
messageProducer.close();
session.close();
connection.close();
//10.提示
System.out.println("消息发送到 mq 完成");
}
}
- 2.控制台:
b:控制台说明:
- 1.总结:
1.当有一个消息 进入这个队列时,等待消费的消息是 1,进入队列的消息是 1.
2.当消息 消费后,等待消费的 消息是 0,出队列的消息是 1.
3.再来一条消息,等待消费的消息是 1 ,进入队列的消息就是 2.
c:消息消费者:(方法一:同步阻塞方法,接收消息之前,一直阻塞状态)
public class MyConsumerMessage {
public static final String ACTIVE_MQ = "tcp://114.215.173.88:61616";
public static final String QUEUE_NAME = "queue_01";
public static void main(String[] args) throws JMSException {
//1.创建 连接工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVE_MQ);
//2. 通过连接工厂,获得连接 Connection
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//3. 创建会话(事务,签收)
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4.创建目的地(具体是队列 还是 主题 topic)
Queue queue = session.createQueue(QUEUE_NAME);
//5.创建消费者
MessageConsumer messageConsumer = session.createConsumer(queue);
//6.创建消费者
while (true) {
//7.死等消息,此方法是:一直等待
//强制类型转换为 text 的消息
TextMessage textMessage = (TextMessage) messageConsumer.receive();
if (textMessage != null) {
System.out.println("消费者接收消息:" + textMessage.getText());
} else {
break;
}
}
//8.关闭
messageConsumer.close();
session.close();
connection.close();
}
}

d:消息消费者:(方法二:通过监听的方式,来接收消息)
public class MyConsumerMessage {
public static final String ACTIVE_MQ = "tcp://114.215.173.88:61616";
public static final String QUEUE_NAME = "queue_01";
public static void main(String[] args) throws JMSException, IOException {
//1.创建 连接工厂
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(ACTIVE_MQ);
//2. 通过连接工厂,获得连接 Connection
Connection connection = activeMQConnectionFactory.createConnection();
connection.start();
//3. 创建会话(事务,签收)
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
//4.创建目的地(具体是队列 还是 主题 topic)
Queue queue = session.createQueue(QUEUE_NAME);
//5.创建消费者
MessageConsumer messageConsumer = session.createConsumer(queue);
//6.创建消费者
// 异步非阻塞方式,创建监听器
// 订阅者 或 接收者,通过 MessageConsumer 的 setMessageListener(MessageListener listener)
//注册一个消息监听器,当消息到达之后,系统自动调用监听器
//MessageListener 的 onMessage(Message message) 方法
messageConsumer.setMessageListener(new MessageListener() {
@Override
public void onMessage(Message message) {
if (message != null && message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
try {
String text = textMessage.getText();
System.out.println("接受消息:" + text);
} catch (JMSException e) {
e.printStackTrace();
}
}
}
});
//保证 控制台不灭
System.in.read();
//8.关闭
messageConsumer.close();
session.close();
connection.close();
}
}
e:编码小总结:
- 1.阻塞 消费者: messageConsumer.receive();两种消费方式。一直阻塞
1.receive():一直等待接收消息。
2.reveive(3000L):等待3000毫秒,4秒,就停止接收消息,过时不候。
- 2.异步 非阻塞 消费者:(监听器)
1.setMessageListener:监听方式,
- 3.问题:
1.问题 1:启动 消费者 1,启动生产者,消费者 1 能消费消息吗?(能)
2.问题 2:再启动消费者 2,消费者 2 还能接收消息吗?(不能)
3.问题 3:启动 消费者 1、消费者 2,发送 6 条消息,怎么接收?(一人一半,平均分配)
- 4.JMS 开发步骤:
- 5.两种消费方式:
1.receive:两种
2.监听器:
- 6.JMS 队列、点对点,总结一下:
1.每个消息,只能有一个消费者,类似 1 对 1 的关系。好比 个人的快递只能自己领取自己的。
2.消息的生产者 和 消费者 直接 没有时间上的相关性。无论消费者 在生产者发送消息的时候,是否处于运行状态,消费者都可以提取消息。好比我们发送短信,发送着发送后,接收者不一定会立即查看。
3.消息被消费后,队列中 不会在存储此消息。所以消费者 不会重复消费。
4.点对点模型是基于队列的:
生产者发消息到队列,消费者从队列接收消息。队列的存在,使得消息的异步传输成为可能。
(和我们平时,给朋友发送短信类似)
5.如果在 Session 关闭时,有部分消息已被收到,但还没有被签收(acknowledged):
那当消费者在此连接到相同的队列时,这些消息还会被再次接收。
6.队列可以长久的保存消息,直到 消费者收到该消息。
消费者不需要 因为担心消息会丢失,而时刻和队列保持激活的连接状态,
充分体现了:异步传输模式的优势。
6)在 发布订阅的 消息传递域中,目的地被称为主题(topic)
a:发布 / 订阅 消息传递域的 特点如下:
- 1.生产者将消息 发布到 topic 中,每个消息,可以有多个消费者。属于 1:N 的关系。
- 2.生产者 和 消费者 之间,有时间上的关联性。
订阅某一个主题的消费者,只能消费 自它订阅之后发布的消息。
- 3.生产者 生产时,topic 不保存消息,它是无状态的、不落地。
假如 无人订阅就去生产,那就是一条废消息。所以,一般先启动消费者,再启动生产者。
- 4.JMS 规范,允许客户创建持久订阅,这在一定程度上,放松了时间上的相关性要求。 持久订阅允许消

本文详细介绍了ActiveMQ的安装、配置、Java编码实现消息通讯,以及JMS规范和ActiveMQ的高级特性,如消息持久化、事务、签收等。文章深入探讨了ActiveMQ在分布式系统中的作用,包括解耦、流量削峰和异步通信,旨在帮助读者理解和掌握ActiveMQ的使用。
最低0.47元/天 解锁文章
1010

被折叠的 条评论
为什么被折叠?



