MQ简单介绍以及RabbitMQ基础使用,快速上手

1.什么是MQ?

MQ( Message queue ), 从字⾯意思上看, 本质是个队列, FIFO 先⼊先出,只不过队列中存放的内容是消息(message) ⽽已. 消息可以⾮常简单,⽐如只包含⽂本字符串, JSON等,也可以很复杂, ⽐如内嵌对象.
MQ多⽤于分布式系统之间进⾏通信.

系统之间通信

1.同步通信

2.异步通信

RabbitMQ就是MQ的一种实现

2.MQ的作用及什么时候使用MQ

MQ主要⼯作是接收并转发消息, 在不同的应⽤场景下可以展现不同的作⽤,可以看一下下面的框图来理解

以下总结了一些使用MQ的场景以及为什么使用

  • 异步解耦:在业务流程中,一些操作可能非常耗时,但并不需要即时返回结果。可以借助 MQ 把这些操作异步化,比如 用户注册后发送注册短信或邮件通知,可以作为异步任务处理,而不必等待这些操作完成后才告知用户注册成功.
  • 流量削峰:在访问量剧增的情况下,应用仍然需要继续发挥作用,但是是这样的突发流量并不常见。如果以能处理这类峰值为标准而投入资源,无疑是巨大的浪费。使用 MQ 能够使关键组件支撑突发访问压力,不会因为突发流量而崩溃。比如秒杀或者促销活动,可以使用 MQ 来控制流量,将请求排队,然后系统根据自己的处理能力逐步处理这些请求.
  • 异步通信:在很多时候应用不需要立即处理消息,MQ 提供了异步处理机制,允许应用把一些消息放入 MQ 中,但并不立即处理它,在需要的时候再慢慢处理.
  • 消息分发:当多个系统需要对同一数据做出响应时,可以使用 MQ 进行消息分发。比如支付成功后,支付系统可以向 MQ 发送消息,其他系统订阅该消息,而无需轮询数据库.(说明MQ可以将一个消息转发给多个对象,一个生产者对应多个消费者)
  • 延迟通知:在需要在特定时间后发送通知的场景中,可以使用 MQ 的延迟消息功能,比如在电子商务平台中,如果用户下单后一定时间内未支付,可以使用延迟队列在超时后自动取消订单

3.RabbitMQ基本概念核心组成

我们必须需要了解一下RabbitMQ的一些基本组成以及处理消息的流程,才能更好的使用写一些关于MQ的代码,可以看一下以下的框图来有个快速的认知

注意一点这里多个消费者可以订阅同一个队列

4.Web界面操作

这里可以通过该界面来查看一下队列的一些情况,这里通过url:服务器ip+端口号(RabbitMQ的WEB端口一般默认为15672,这里如果为rabbitmq的web端口配置了隧道就使用隧道端口) 来访问,这里需要账号和密码来登录,我的账号密码是:admin,admin

5.RabbitMQ配置与使用

需要添加依赖

java 复制代码
<!-- RabbitMQ -->
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

需要添加的配置项(.properties)

java 复制代码
## mq ##
#安装Rabbitmq服务器地址
spring.rabbitmq.host=IP地址
#rabbit服务的业务端口号(一般为5672,这里如果专门配置了隧道使用隧道的端口)
spring.rabbitmq.port=端口号
spring.rabbitmq.username=用户名
spring.rabbitmq.password=密码
#消息确认机制,默认auto
spring.rabbitmq.listener.simple.acknowledge-mode=auto
#设置失败重试 5次
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=5

确认机制:这里可以看一下这里的自动确认机制,首先明白什么叫确认,比如消息队列想要知道消费者拿了消息之后消费了吗,这个是需要消费者来告诉的,而中这个自动确认机制就是,消费者拿到消息之后处理后,没有抛出异常,就默认是消费成功了,而当消费者在消费消息方法中抛出了异常,MQ就认定你消费失败了,这就是自动确认机制spring.rabbitmq.listener.simple.acknowledge-mode=auto

当然除了自动确认机制还有手动确认机制,这个就是由消费者手动返回告诉消息队列是否消费成功,还有比如,消息队列给消费者发后,不管消费者是否消费都直接默认算你消费成功了,以上就说了三种确认机制,当然还有别的确认机制可以自行去了解

失败重试:这个就是当确认消费者消费失败以后,消息队列重新向消费者发消息的最大次数,

通过这两个我们可以确保一些必须要做的事情,就算失败了也要重做

需要的配置类

java 复制代码
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * RabbitMQ 直连交换机(Direct Exchange)配置类
 */
@Configuration
public class DirectRabbitConfig {

    // 队列名称
    public static final String QUEUE_NAME = "DirectQueue";
    // 交换机名称
    public static final String EXCHANGE_NAME = "DirectExchange";
    // 路由键
    public static final String ROUTING = "DirectRouting";

    /**
     * 声明直连队列
     * durable: 是否持久化(默认false),持久化队列会存储在磁盘,MQ重启后仍存在;暂存队列仅当前连接有效
     * exclusive: 是否排他(默认false),排他队列仅当前连接可用,连接关闭后自动删除,优先级高于durable
     * autoDelete: 是否自动删除(默认false),无生产者/消费者使用时自动删除
     *
     * @return 直连队列实例
     */
    @Bean
    public Queue directQueue() {
        // 一般仅设置队列持久化,其余参数使用默认值(false)
        return new Queue(QUEUE_NAME, true);
    }

    /**
     * 声明直连交换机
     *
     * @return 直连交换机实例
     */
    @Bean
    public DirectExchange directExchange() {
        // 参数:交换机名称、是否持久化、是否自动删除
        return new DirectExchange(EXCHANGE_NAME, true, false);
    }

    /**
     * 绑定队列和交换机,并指定匹配的路由键
     *
     * @return 绑定关系实例
     */
    @Bean
    public Binding bindingDirect() {
        return BindingBuilder.bind(directQueue())
                .to(directExchange())
                .with(ROUTING);
    }

    /**
     * 配置消息转换器,将消息序列化为JSON格式
     *
     * @return JSON消息转换器
     */
    @Bean
    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }
}

该类仔细阅读一下,其实就是

设置队列的名称,并设置持久化,

设置交换机的名称,并设置持久化,不会自动删除,

绑定了队列和交换机,并绑定了一个key(路由键),这样子我们通过他来指定放到哪个队列里面去

最后设置了一下消息的转换格式就算将消息序列化为JSON

配置完rabbitmq其实就等于我们将 生产者-消息队列-消费者 中消息队列部分的代码写完了,这里我们只需要完成生产者的代码,以及消费者代码即可

相关推荐
躺平大鹅7 小时前
Java面向对象入门(类与对象,新手秒懂)
java
用户8307196840828 小时前
RabbitMQ vs RocketMQ 事务大对决:一个在“裸奔”,一个在“开挂”?
后端·rabbitmq·rocketmq
初次攀爬者8 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺8 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart9 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP10 小时前
MyBatis-mybatis入门与增删改查
java
孟陬13 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端
想用offer打牌13 小时前
一站式了解四种限流算法
java·后端·go
华仔啊14 小时前
Java 开发千万别给布尔变量加 is 前缀!很容易背锅
java