👨🎓作者:bug菌
✏️博客:CSDN、掘金、infoQ、51CTO等
🎉简介:CSDN博客专家,C站历届博客之星Top50,掘金/InfoQ/51CTO等社区优质创作者,全网合计8w粉+,对一切技术感兴趣,重心偏Java方向;硬核公众号「 猿圈奇妙屋」,欢迎小伙伴们的加入,一起秃头,一起变强。
..
✍️温馨提醒:本文字数:1999字, 阅读完需:约 5 分钟
嗨,家人们,我是bug菌呀,我又来啦。今天我们来聊点什么咧,OK,接着为大家更《springboot零基础入门教学》系列文章吧。希望能帮助更多的初学者们快速入门!
小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章点亮👍吧,您的点赞三连(收藏⭐+关注👨🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻♀️,创作不停💕,加油☘️
一、前言🔥
环境说明:Windows10 + Idea2021.3.2 + Jdk1.8 + SpringBoot 2.3.1.RELEASE
之前我在开发商城项目的时候,有接触过这么一块订单与库存模板,由于并发不是很大就一直搁置,然后我现在回想起来,完全可以用现在的高性能中间件来处理以降低两模块之间的耦合度,这也是我今天要介绍的东西--消息中间件之消息队列[RabbitMq],闲暇时间对此有进行一些学习了解☃️,下面是学习内容的总结。
借此想分享给大家, 希望能帮助那些还未入门的小伙伴们,在学完本期文章内容,你将会对RabbitMq有一个基本的认识,而不再是它认识你,你不认识它。具有很好的学习价值,大家请跟我来吧👀。
在此之前,请大家先安装好RabbitMq Server服务端,否则后边没法玩儿啦,推荐大家看我上期为大家准备的安装篇,非常详细《Windows10本地搭建RabbitMq Server服务端》
二、概念
下面,我先来给大家科普一下,消息队列相关的一些基础概念吧。使用前先了解它是什么,为什么用它,它有那些优劣,什么场景下使用适合等,带着这些疑问来本文探寻吧,对你日后开发使用也是及有帮助🔮。
1、什么是消息队列
首先我们先来解读一下什么是消息(Message)
。指在应用之间传送的数据被称为消息。消息的内容可以非常简单,比如只包含文本字符串,也可以非常的复杂,比如包含嵌入对象,根据你实际场景而定。
消息队列(Message Queue)
则是一种应用之间的通信方式。消息发送后可以立即返回,由消息系统来确保信息的可靠传输。消息发布者只需把消息发布并传送到队列中,消息使用者只管从队列中取走消息并处理,这样发布者和使用者都不需要知道对方的存在,从而达到解耦的目的。
2、为什么要使用消息队列
- **提高系统响应速度
**
使用消息队列,生产者一方,把消息往消息队列里一扔,就可以立马返回响应用户,无需等待处理结果
- **保证消息的传递
**
如果发送消息时接收者不可用,消息队列会保留消息,直到成功传递它为止。
- 解耦
只要信息格式不变,即使接收者的接口、位置、或者配置改变,也不会给发送者带来任何改变 消息发送者无需知道消息接收者是谁,使得系统设计更清晰 。
3、RabbitMq是什么
RabbitMq属于消息队列的一种。对于消息队列,我们一般知道有三个概念:发消息者、队列、收消息者,RabbitMQ 在这个基本概念之上,多做了一层抽象,在发消息者和队列之间,加入了交换器(Exchange)这样发消息者和队列就没有直接联系,转而变成发消息者把消息给交换器,交换器根据调度策略再把消息再给队列。
RabbitMQ是一个由 Erlang
开发的AMQP(Advanced Message Queuing Protocol)
开源实现。服务器端用Erlang
语言编写,支持多种客户端,比如:Python、Java、PHP、C等,且支持Ajax。在分布式系统中对消息的存储转发,在易用性、扩展性、高可用性等方面上也表现不俗。
RabbitMQ主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。
拓展:
AMQP:高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。
4、RabbitMQ的特点
- 可靠性
RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认等。
- 灵活路由
在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个 Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。
- 消息集群
多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker 。
- 高可用
队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。
- 多种协议
RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。
- 多语言客户端
RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等等
- 管理界面
RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。
- 跟踪机制
如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。
- 插件机制
RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。
5、RabbitMQ 基本概念
- Message
消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。
- Publisher
消息的生产者,也是一个向交换器发布消息的客户端应用程序。
- Exchange
交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。
- Routing Key
路由关键字,exchange根据这个关键字进行消息投递。
- Binding
绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。
- Queue
消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。
- Broker
表示消息队列服务器实体。
... ...
6、RabbitMQ的应用场景
- 异步处理
场景:用户注册
用户注册后,需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 。
引入消息队列后:
可以把发送邮件,短信不是必须的业务逻辑异步处理。
- 应用解耦
场景:比如商城的订单系统与库存系统。
传统是用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口。这样做法的有个严重的弊端:当库存系统出现故障时,订单就会失败。
引入消息队列后:
用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户显示下单成功。库存系统:订阅下单的消息,获取下单消息,进行库操作。就算库存(货物信息)系统出现故障,消息队列也能保证消息(订单信息)的可靠投递,不会导致消息(订单信息)丢失。
- 流量削峰
场景:比如秒杀活动。
一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。
引入消息队列后:
- 可以控制活动人数,超过此一定阀值的订单直接丢弃。
- 可以缓解短时间的高流量压垮应用。
三、本地安装RabbitMq客户端
这里推荐大家看我上期写的搭建教程:《Windows10本地搭建RabbitMq Server服务端》
我就不给安装大家演示啦。归纳总结主要就是如下两点安装步骤。
然后附上了官网下载地址,方便大家下载使用。
四、添加RabbitMq依赖
springboot也对RabbitMq做了相应的集成,所以我们直接拿来用就可以了,在你们的pom.xml配置中直接添加如下配置即可。
<!-- rabbitmq依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
五、简单Rabbit使用演示
第一步:配置mq服务
spring:
#配置rabbitMq 服务器
rabbitmq:
#设置RabbitMQ的IP地址
host: 127.0.0.1
#设置rabbitmq服务器连接端口
port: 5672
#设置rabbitmq服务器用户名 本地搭建对应的账户密码都是 guest
username: guest
#设置rabbitmq服务器密码
password: guest
拓展:
如果修改过IP、端口号、账号、密码以上内容则需要重新指定。未修改都是如下默认:
默认使用IP:127.0.0.1
默认使用端口号:5672
默认使用账号:guest
默认使用密码:guest
15672:控制台端口号
5672:应用访问端口号 //所以配置文件配置的端口是5672而不是15672.
如上就已经配置连接了Server端,查看是否能正常连接,就看生产者能否往队列里发消息了。
第二步:RabbitMq配置
这里我们先来定义一个Rabbitmq配置类,目的是先定义好一个队列,待会儿就直接往这个队列中写入消息。
package com.example.demo.config;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 声明一个队列
*
* @author luoYong
* @version 1.0
* @date 2022/2/24 17:10
*/
@Configuration
public class RabbitMqConfig {
/**
* 初始化Queue
* 创建一个名称为"luoyong-queue"的队列,其他参数使用默认
* 在创建队列的时候如果要指定其他参数,Queue有多个构造方法可选择
*/
@Bean
public Queue helloQueue() {
return new Queue("luoyong-queue");
}
}
接下来,我给大家演示一下RabbitMQ 的五种工作模式之最简单的--简单队列
一个生产者只对应一个消费者!我们先来定义一个生产者。
具体实现代码如下:
package com.example.demo.component.RabbitMq;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* 生产者
*
* @author luoYong
* @version 1.0
* @date 2022/2/24 17:16
*/
@Component
public class RabbitSender {
@Autowired
private AmqpTemplate rabbitTemplate;
/**
* 发送消息
*/
public void sendMsg() {
String msg = "简单队列-hello呀";
System.out.println("Sender : " + msg);
this.rabbitTemplate.convertAndSend("luoyong-queue", msg);
}
}
在简单队列模型中,发送消息的时候不指定交换机的名称,那么就会发送到"默认交换机"上。默认的Exchange不进行Binding操作,任何发送到该Exchange的消息都会被转发到"Queue名字和Routing key相同的队列"中,如果vhost中不存在和Routing key同名的队列,则该消息会被抛弃。
这里我们在发送消息的时候设置的Routing key为"luoyong-queue
",那么就会发送到队列名字为"felix-queue"的队列上去。
我们再来定义一个 消费者。
具体实现代码如下:
package com.example.demo.component.RabbitMq;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
* 消费者
*
* @author luoYong
* @version 1.0
* @date
2022/2/24 17:19
*/
@Component
@RabbitListener(queues = "luoyong-queue") //指定队列
public class RabbitReceiver {
@RabbitHandler
public void process(String msg) {
System.out.println("Receiver : 消费成功:" + msg);
}
}
接下来我们来定义一个测试类,测试生产者发送消息功能。
package com.example.demo.component.RabbitMq;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
* @author luoYong
* @version 1.0
* @date 2022/2/24 17:02
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RabbitMqConfigTest {
@Autowired
private RabbitSender rabbitSender;
// 发送单条消息
@Test
public void contextLoads() {
rabbitSender.sendMsg();
}
}
第三步:测试生产者
1、测试生产者
测试类启动运行之后,登陆Server端界面,可以看到队列中阻塞了一条消息未消费。
只要未被消费,就一直存在着等待消费,。
2、运行消费者
接下来我们就来启动项目,消息就会被自然消费掉,然后一有消息就进行消费,消费完了之后继续等待。
也可以查看控制台,成功拿到了之前被生产的那条消息。证明消费成功了。
接下来我们在保持项目启动的状态下,我们再运行一下生产测试类,往队列里再发送一条消息,看看消息会不会被被立马消费?
查看Server端,很明显,消息一瞬间就被消费了,Ready = 0,则线图也有波动。
最明显的就是看你的控制台,看看消费者是否执行有消息打印。
... ...
ok,以上就是我这期的全部内容啦,如果还想学习更多,你可以看看我的往期热文推荐哦,每天积累一个奇淫小知识,日积月累下去,你一定能成为令人敬仰的大佬的。好啦,咱们下期见~
六、往期热门推荐
- springboot系列(一):如何创建springboot项目及启动
- springboot系列(二):yaml、properties两配置文件介绍及使用
- springboot系列(三):多环境切换,实例演示
- springboot系列(四):stater入门
- springboot系列(五):史上最最最全springboot常用注解
- springboot系列(六):mysql配置及数据库查询
- springboot系列(七):如何通过mybatis-plus实现接口增删改查
- springboot系列(八):mybatis-plus之条件构造器使用手册
- springboot系列(九):mybatis-plus之如何自定义sql
- springboot系列(十):mybatis之xml映射文件>、<=等特殊符号写法
- springboot系列(十一):实现多数据源配置,开箱即用
- springboot系列(十二):如何实现邮件发送提醒,你一定得会(准备篇)
- springboot系列(十三):如何实现发送普通邮件?你一定得会
- springboot系列(十四):如何实现发送图片、doc文档等附件邮件?你一定得会
- springboot系列(十五):如何实现静态邮件模板发送?你一定得会
- springboot系列(十六):如何实现发送邮件提醒,附完整源码
- springboot系列(十七):集成在线接口文档Swagger2
- springboot系列(十八):如何Windows安装redis?你玩过么
- springboot系列(十九):如何集成redis?不会我教你
- springboot系列(二十):如何通过redis实现手机号验证码功能
- ... ...
文末🔥
如果还想要学习更多,小伙伴们可关注bug菌专门为大家创建的专栏《springboot零基础入门教学》,从无到有,从零到一!希望能帮助到更多小伙伴们。
我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!
感谢认真读完我博客的铁子萌,在这里呢送给大家一句话,不管你是在职还是在读,绝对终身受用。
时刻警醒自己:
抱怨没有用,一切靠自己;
想要过更好的生活,那就要逼着自己变的更强,生活加油!!!