> 文档中心 > Springboot如何整合RabbitMq?若不会,我便手把手教你【超级详细】

Springboot如何整合RabbitMq?若不会,我便手把手教你【超级详细】


👨‍🎓作者:bug菌

✏️博客:CSDN、掘金等

💌公众号:猿圈奇妙屋

🚫特别声明:原创不易,转载请附上原文出处链接和本文声明,谢谢配合。

🙏版权声明:文章里可能部分文字或者图片来源于互联网或者百度百科,如有侵权请联系bug菌处理。

【开发云】年年都是折扣价,不用四处薅羊毛

         嗨,家人们,我是bug菌呀,我又来啦。今天我们来聊点什么咧,OK,接着为大家更《springboot零基础入门教学》系列文章吧。希望能帮助更多的初学者们快速入门!

       小伙伴们在批阅文章的过程中如果觉得文章对您有一丝丝帮助,还请别吝啬您手里的赞呀,大胆的把文章 点亮👍吧,您的点赞三连( 收藏⭐️+关注👨‍🎓+留言📃)就是对bug菌我创作道路上最好的鼓励与支持😘。时光不弃🏃🏻‍♀️,创作不停💕,加油☘️

一、前言🔥

       之前我在开发商城项目的时候,有接触过这么一块订单与库存模板,由于并发不是很大就一直搁置,然后我现在回想起来,完全可以用现在的高性能中间件来处理以降低两模块之间的耦合度,这也是我今天要介绍的东西--消息中间件之消息队列[RabbitMq],闲暇时间对此有进行一些学习了解☃️,下面是学习内容的总结。

       借此想分享给大家, 希望能帮助那些还未入门的小伙伴们,在学完本期文章内容,你将会对RabbitMq有一个基本的认识,而不再是它认识你,你不认识它。具有很好的学习价值,大家请跟我来吧👀。

       在此之前,请大家先安装好RabbitMq Server服务端,否则后边没法玩儿啦,推荐大家看我上期为大家准备的安装篇,非常详细《Windows10如何搭建RabbitMq Server服务端?我手把手教你!》

二、概念🔥

       下面,我先来给大家科普一下,消息队列相关的一些基础概念吧。使用前先了解它是什么,为什么用它,它有那些优劣,什么场景下使用适合等,带着这些疑问来本文探寻吧,对你日后开发使用也是及有帮助🔮。

1️⃣什么是消息队列

       首先我们先来解读一下什么是消息(Message)。指在应用之间传送的数据被称为消息。消息的内容可以非常简单,比如只包含文本字符串,也可以非常的复杂,比如包含嵌入对象,根据你实际场景而定。 

       消息队列(Message Queue)则是一种应用之间的通信方式。消息发送后可以立即返回,由消息系统来确保信息的可靠传输。消息发布者只需把消息发布并传送到队列中,消息使用者只管从队列中取走消息并处理,这样发布者和使用者都不需要知道对方的存在,从而达到解耦的目的。

2️⃣为什么要使用消息队列

  • 1、提高系统响应速度

       使用消息队列,生产者一方,把消息往消息队列里一扔,就可以立马返回响应用户,无需等待处理结果。

  • 2、保证消息的传递

       如果发送消息时接收者不可用,消息队列会保留消息,直到成功传递它为止。

  • 3、解耦

       只要信息格式不变,即使接收者的接口、位置、或者配置改变,也不会给发送者带来任何改变 消息发送者无需知道消息接收者是谁,使得系统设计更清晰 。

3️⃣RabbitMq是什么

       RabbitMq属于消息队列的一种。对于消息队列,我们一般知道有三个概念:发消息者、队列、收消息者,RabbitMQ 在这个基本概念之上,多做了一层抽象,在发消息者和队列之间,加入了交换器(Exchange)这样发消息者和队列就没有直接联系,转而变成发消息者把消息给交换器,交换器根据调度策略再把消息再给队列。

       RabbitMQ是一个由 Erlang 开发的AMQP(Advanced Message Queuing Protocol)开源实现。服务器端用Erlang语言编写,支持多种客户端,比如:Python、Java、PHP、C等,且支持Ajax。在分布式系统中对消息的存储转发,在易用性、扩展性、高可用性等方面上也表现不俗。

       RabbitMQ主要是用来实现应用程序的异步和解耦,同时也能起到消息缓冲,消息分发的作用。

拓展:
       AMQP:高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。

4️⃣RabbitMQ有何特点

  • 1、可靠性

       RabbitMQ 使用一些机制来保证可靠性,如持久化、传输确认、发布确认等。

  • 2、灵活路由

       在消息进入队列之前,通过 Exchange 来路由消息的。对于典型的路由功能,RabbitMQ 已经提供了一些内置的 Exchange 来实现。针对更复杂的路由功能,可以将多个 Exchange 绑定在一起,也通过插件机制实现自己的 Exchange 。

  • 3、消息集群

       多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker 。

  • 4、高可用

       队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用。

  • 5、多种协议

       RabbitMQ 支持多种消息队列协议,比如 STOMP、MQTT 等等。

  • 6、多语言客户端

       RabbitMQ 几乎支持所有常用语言,比如 Java、.NET、Ruby 等等

  • 7、管理界面

       RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息 Broker 的许多方面。

  • 8、跟踪机制

       如果消息异常,RabbitMQ 提供了消息跟踪机制,使用者可以找出发生了什么。

  • 9、插件机制

       RabbitMQ 提供了许多插件,来从多方面进行扩展,也可以编写自己的插件。

5️⃣RabbitMQ 基本概念

  • 1、Message

       消息,消息是不具名的,它由消息头和消息体组成。消息体是不透明的,而消息头则由一系列的可选属性组成,这些属性包括routing-key(路由键)、priority(相对于其他消息的优先权)、delivery-mode(指出该消息可能需要持久性存储)等。

  • 2、Publisher

       消息的生产者,也是一个向交换器发布消息的客户端应用程序。

  • 3、Exchange

       交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。

  • 4、Routing Key

       路由关键字,exchange根据这个关键字进行消息投递。

  • 5、Binding

       绑定,用于消息队列和交换器之间的关联。一个绑定就是基于路由键将交换器和消息队列连接起来的路由规则,所以可以将交换器理解成一个由绑定构成的路由表。

  • 6、Queue

       消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

  • 7、Broker

       表示消息队列服务器实体。

... ...

6️⃣RabbitMQ的应用场景

  • 1、异步处理

场景:用户注册

用户注册后,需要发注册邮件和注册短信,传统的做法有两种1.串行的方式;2.并行的方式 。

引入消息队列后:

可以把发送邮件,短信不是必须的业务逻辑异步处理。

  • 2、应用解耦

场景:比如商城的订单系统与库存系统。

       传统是用户下单后,订单系统需要通知库存系统,传统的做法就是订单系统调用库存系统的接口。这样做法的有个严重的弊端:当库存系统出现故障时,订单就会失败。

引入消息队列后:

用户下单后,订单系统完成持久化处理,将消息写入消息队列,返回用户显示下单成功。库存系统:订阅下单的消息,获取下单消息,进行库操作。就算库存(货物信息)系统出现故障,消息队列也能保证消息(订单信息)的可靠投递,不会导致消息(订单信息)丢失。

  • 3、流量削峰

场景:比如秒杀活动。

一般会因为流量过大,导致应用挂掉,为了解决这个问题,一般在应用前端加入消息队列。

引入消息队列后:

  • 可以控制活动人数,超过此一定阀值的订单直接丢弃。
  • 可以缓解短时间的高流量压垮应用。

三、本地安装RabbitMq客户端🔥

这里推荐大家看我上期写的搭建教程:《windows如何本地搭建RabbitMq客户端》。

我就不给安装大家演示啦。归纳总结主要就是如下两点安装步骤。

然后附上了官网下载地址,方便大家下载使用。

  1. 安装erlang环境
  2. 安装RabbitMq客户端

四、添加RabbitMq依赖🔥

       springboot也对RabbitMq做了相应的集成,所以我们直接拿来用就可以了,在你们的pom.xml配置中直接添加如下配置即可。

    org.springframework.boot    spring-boot-starter-amqp

五、简单Rabbit使用演示🔥

1️⃣配置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端,查看是否能正常连接,就看生产者能否往队列里发消息了。

2️⃣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 */@Configurationpublic 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 */@Componentpublic 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();    }}

3️⃣测试生产者

1、测试生产者

        测试类启动运行之后,登陆Server端界面,可以看到队列中阻塞了一条消息未消费。

只要未被消费,就一直存在着等待消费,。

2、运行消费者

       接下来我们就来启动项目,消息就会被自然消费掉,然后一有消息就进行消费,消费完了之后继续等待。

也可以查看控制台,成功拿到了之前被生产的那条消息。证明消费成功了。

        接下来我们在保持项目启动的状态下,我们再运行一下生产测试类,往队列里再发送一条消息,看看消息会不会被被立马消费?

        查看Server端,很明显,消息一瞬间就被消费了,Ready = 0,折线图也有波动。

        最明显的就是看你的控制台,看看消费者是否执行有消息打印。

       ... ...

       ok,以上就是我这期的全部内容啦,如果还想学习更多,你可以看看我的往期热文推荐哦,每天积累一个奇淫小知识,日积月累下去,你一定能成为令人敬仰的大佬的。好啦,咱们下期见~

六、文末🔥

       如果还想要学习更多,小伙伴们可关注bug菌专门为大家创建的专栏《springboot零基础入门教学》,从无到有,从零到一!希望能帮助到更多小伙伴们。

【开发云】年年都是折扣价,不用四处薅羊毛

       我是bug菌,一名想走👣出大山改变命运的程序猿。接下来的路还很长,都等待着我们去突破、去挑战。来吧,小伙伴们,我们一起加油!未来皆可期,fighting!

        最后送大家两句我很喜欢的话,与诸君共勉!


☘️做你想做的人,没有时间限制,只要愿意,什么时候都可以start。

🍀你能从现在开始改变,也可以一成不变,这件事,没有规矩可言,你可以活出最精彩的自己。


​​​

💌如果文章对您有所帮助,就请留下您的吧!(#^.^#);

💝如果喜欢bug菌分享的文章,就请给bug菌点个关注吧!(๑′ᴗ‵๑)づ╭❤~;

💗如果对文章有任何疑问,还请文末留言或者加群吧【QQ交流群:708072830】;

💞鉴于个人经验有限,所有观点及技术研点,如有异议,请直接回复参与讨论(请勿发表攻击言论,谢谢);

💕版权声明:原创不易,转载请附上原文出处链接和本文声明,版权所有,盗版必究!!!谢谢。