一、RabbitMQ安装及介绍

131 阅读7分钟

Message Queue(消息 队列),从字⾯上理解:⾸先它是⼀个队列。遵循 FIFO 先进先出 的数据结构———队列。消息队列就是所谓的存放消息的队列。
消息队列解决的不是存放消息的队列的⽬的,解决的是通信问题。

一、应用场景

1.1、流量削峰

举个例子,如果订单系统最多能处理一万次订单,这个处理能力应付正常时段的下单时绰绰有余,正 常时段我们下单一秒后就能返回结果。但是在高峰期,如果有两万次下单操作系统是处理不了的,只能限 制订单超过一万后不允许用户下单。使用消息队列做缓冲,我们可以取消这个限制,把一秒内下的订单分 散成一段时间来处理,这时有些用户可能在下单十几秒后才能收到下单成功的操作,但是比不能下单的体 验要好。

1.2、应用解耦 异步调用

1.2.1、传统模式下

image.png

如图所示:对于 创建订单扣减库存加积分优惠券、这些操作

  • 传统模式下只能 同步操作 耗时会比较长,而且整个过程会受网络波动的影响,并且可能某次调用失败后整个调用链路都会收到影响
1.2.2、消息队列方式

image.png

使⽤异步的通信⽅式对模块间的调⽤进⾏解耦,可以快速的提升系统的吞吐量。上游执⾏完消息的发送业务后⽴即获得结果,下游多个服务订阅到消息后各⾃消费。

通过消息队列,屏蔽底层的通信协议,使得解藕和并⾏消费得以实现。

二、介绍

市⾯上⽐较⽕爆的⼏款MQ:ActiveMQ,RocketMQ,Kafka,RabbitMQ。
语⾔的⽀持: ActiveMQ,RocketMQ只⽀持Java语⾔,Kafka可以⽀持多们语⾔,RabbitMQ⽀持多种语⾔。
效率⽅⾯: ActiveMQ,RocketMQ,Kafka效率都是毫秒级别,RabbitMQ是微秒级别的。
消息丢失,消息重复问题: RabbitMQ针对消息的持久化,和重复问题都有比较成熟的解决方案。
RabbitMQ严格的遵循 AMQP协议,高级消息队列协议,帮助我们在进程之间传递异步消息。

RabbitMQ官网:rabbitmq.com/

三、安装

官方安装方式:rabbitmq.com/download.ht…

方式安装选其一即可

3.1、docker方式安装

# latest RabbitMQ 3.11
docker run -it --rm --name rabbitmq -p 5672:5672 -p 15672:15672 rabbitmq:3.11-management

3.2、docker-compose方式安装

3.2.1、编写docker-compose.yml
version: "3.1"
services:
  rabbitmq:
    image: daocloud.io/library/rabbitmq:management
    restart: always
    container_name: rabbitmq
    ports:
      - 5672:5672
      - 15672:15672
    volumes:
      - ./data:/var/lib/rabbitmq
3.2.2、运行
# 在docker-compose.yml文件所在的目录下执行,以后台方式运行
docker compose up -d

3.3、开放15672端口

防火墙开放端口:juejin.cn/post/715943…

# 开放15672端口
firewall-cmd --zone=public --add-port=15672/tcp --permanent
# 更新配置信息(这样就不需要重启防火墙了) 
firewall-cmd --reload

3.4、访问测试

http://192.168.68.68:15672/
账号密码:guest

image.png

四、RabbitMQ架构

4.1、简单架构图

  • Publisher - ⽣产者:发布消息到RabbitMQ中的Exchange
  • Consumer - 消费者:监听RabbitMQ中的Queue中的消息
  • Exchange - 交换机:和⽣产者建⽴连接并接收⽣产者的消息
  • Queue - 队列:Exchange会将消息分发到指定的Queue,Queue和消费者进⾏交互
  • Routes - 路由:交换机以什么样的策略将消息发布到Queue

image.png

4.2、虚拟主机

image.png

五、RabbitMQ队列模式

5.1、简单队列模式

image.png

  • 生产者:使用默认的交换机,可以直接创建队列,
  • 消费者:只有一个消费者来处理消息

5.2、work队列模式(WorkQueues)

一个消息只能被处理一次,不允许重复消费,采用轮询的方式分发消息

image.png

  • 生产者:使用默认的交换机,可以直接创建队列,
  • 消费者:可以有一个或多个消费者,轮训接收消息

弊端:当多个消费者消费同一个队列时,如果某个消费者消费能力弱(耗时较长)时,其他消费者会等待这个消费者消费完毕后才能进行消费

5.3、发布订阅模式(Publish/Subscribe)

该模式下消费者都有自己的队列,比如 生产者 生产100条消息,那么所有的消费者都可从队列中拿到100条消息。举个例子,公众号中,号主发布一篇文章,所有的关注者都会收到消息。

image.png

5.3.1、交换机(Exchange)

发布订阅模式 引入了交换机的概念,他一方面,用来接收生产者发送的消息。另一方面,知道如何处理消息,例如传递给某个特别的队列、提交给所有队列、或者将消息丢弃。到底如何操作,取决于Exchange的类型。常见的 Exchange 有以下三种类型:

  • Fanout:广播 ,将消息交给所有绑定到交换机的队列
  • Direct:定向 ,把消息交给符合指定 routing key 的队列
  • Topic:通配符 ,把消息交给符合 routing pattern(路由模式) 的队列

交换机只用于消息的转发,不具备存储消息的能力,因此队列需要和交换机需要和队列做绑定,否则就收不到消息。如果没有符合路由规则的队列,那么消息会丢失!

5.4、路由工作模式(Routing)

image.png

一个交换机可以绑定一个或多个 Routing Key

5.5、主题模式(Topics)

通配符模式

image.png

四、消息的可靠投递

在使用RabbitMQ的时候,作为消息发送方 希望杜绝任何消息丢失或者投递失败场景 。RabbitMQ为我们提供了 两种方式用来控制消息的投递可靠性模式

  • confirm确认模式
  • return退回模式

rabbitmg整个消息投递的路径为: Producer ---> Exchange ---> Queue ---> Consumer

Producer 将消息发送到指定 ExchangeExchange 收到消息后再将消息通过 RoutingKey 的方式路由的 Queue队列 暂存消息, Consumer 监听队列,拿到对应的消息数据

在整个投递过程中任何一个环节都有可能投递失败:

  • 消息从 producer 到 exchange 则会返回一个 confirmCallback 。
  • 消息从 exchange–>queue 投递失败则会返回一个 returnCallback 。
  • ACK 消费者收到消息后确认
    • 自动确认acknowledge=“none”:当消费者接收到消息的时候,就会自动给到RabbitMQ一个回执,告诉MQ我已经收到消息了,不在乎消费者接收到消息之后业务处理的成功与否。
    • 手动确认acknowledge=“manual”:当消费者收到消息后,不会立刻告诉RabbitMQ已经收到消息了,而是等待业务处理成功后,通过调用代码的方式手动向MQ确认消息已经收到。当业务处理失败,就可以做一些重试机制,甚至让MQ重新向消费者发送消息都是可以的。
    • 根据异常情况确认acknowledge=“auto”:该方式是通过抛出异常的类型,来做响应的处理(如重发、确认等)。这种方式比较麻烦,一般不用。

五、TTL

  • TTL全称Time To Live(存活时间/过期时间)。
  • 当消息到达存活时间后,还没有被消费,会被自动清除。
  • RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间。

六、死信队列 Dead Letter Exchange(死信交换机)

死信队列,英文缩写:DX。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是死信交换机。

image.png

队列绑定死信交换机: 给队列设置参数:x-dead-letter--exchange 死信交换机名称 和 x-dead-letter-routing-key 死信交换机绑定的RoutingKey

死信队列实现方式:
    1、声明正常的队列(boot_queue)和交换机(boot_exchange)
    2、声明死信队列(boot_queue_dlx)和死信交换机(boot_exchange_dlx)
    3、正常队列绑定死信交换机
        需设置两个参数:
            x-dead-letter-exchange:死信交换机名称
            x-dead-letter-routing-key:发送给死信交换机的 routingkey