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其实就等于我们将 生产者-消息队列-消费者 中消息队列部分的代码写完了,这里我们只需要完成生产者的代码,以及消费者代码即可

相关推荐
荒诞硬汉1 分钟前
面向对象(三)
java·开发语言
柒.梧.5 分钟前
Spring Boot集成JWT Token实现认证授权完整实践
java·spring boot·后端
白露与泡影5 分钟前
放弃 IntelliJ IDEA,转 VS Code 了。。
java·ide·intellij-idea
独自破碎E6 分钟前
在RabbitMQ中,怎么确保消息不会丢失?
分布式·rabbitmq
迷雾骑士7 分钟前
IDEA中将项目提交到Gitee仓库
java·gitee·intellij-idea
Java 码农8 分钟前
RabbitMQ集群部署方案及配置指南02
分布式·rabbitmq
菜鸟233号9 分钟前
力扣416 分割等和子串 java实现
java·数据结构·算法·leetcode
奔波霸的伶俐虫12 分钟前
redisTemplate.opsForList()里面方法怎么用
java·开发语言·数据库·python·sql
自在极意功。14 分钟前
简单介绍SpringAOP
java·spring·aop思想
虫小宝14 分钟前
京东返利app分布式追踪系统:基于SkyWalking的全链路问题定位
分布式·skywalking