RabbitMQ

MQ基本概念

一 MQ基本概念

Message Queue(消息队列),是在消息的传输过程中保存消息的容器,多用于分布式系统间进行通信

优势

应用解耦

异步提速

削峰填谷

image-20201204161620908

image-20201204161649794

劣势

系统可用性降低

系统复杂度提高

一致性问题

MQ产品

RabbitMQ,ActiveMQ,ocketMQ,Kafka

image-20201204162302991

RabbitMQ 简介

2007年Rabbit技术公司基于AMQP标准开发的RabbitMQ 1.0发布。采用Erlang语言开发,Erlang语言由Ericson设计,专门为开发高并发和分布式系统的一种语言,在电信领域广泛应用。

AMQP

Advanced Message Queuing Protocol 高级消息队列协议,是一个网络协议,是应用层协议的一个开发标准,为面向消息的中间件设计。基于此消息的客户端与消息中间件可传递消息,并不受客户端/中间件不同产品,不同的开发语言等限制。2006年AMQP规范发布。类比HTTP。

image-20201204163255693

基础架构

image-20201204163406291

工作模式

简单模式、work queues、Publish/Subscribe发布与订阅模式、Routing路由模式、Topics主题模式、RPS远程调用模式(远程调用不太算MQ)

image-20201204164500501

JMS

JavaMessage Service,Java消息服务应用程序接口,是一个JAVA平台中关于面向消息中间件的API.

JMS是J2EE规范的一种类比JDBC

很多消息中间件都实现了JMS规范,例如ActiveMQ。RabbitMQ官方没有提供实现包,但是开源社区有

二 RabbitMQ安装和配置

在Docker中安装

### 拉取镜像
docker pull rabbitmq:3.8.8-management

### 构建容器
docker create --name RabbitMQ -t -p 5672:5672 -p 15672:15672 rabbitmq:3.8.8-management

### 启动镜像
docker start RabbitMQ && docker logs -f RabbitMQ


三RabbitMQ 工作模式

Work queues工作队列模式

1、模式说明

image-20201208134835337

Work Queues 与入门程序的简单模式相比,多了一个或者一些消费端,多个消费端共同消费同一队列的消息

应用场景:对于任务过重或任务较多情况使用工作队列可以提高任务处理速度

2、小结

在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争关系

Work Queues 对于任务较重或者任务较多情况使用工作队列可以提高任务处理的速度,例如:短信服务部署多个,只需要有一个节点发送成功即可

Pub/Sub订阅模式

image-20201208141405406

1、模式说明

在订阅模式中多了一个Exchange角色,而且过程略有变化:

P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发送给X(交换机)

C:消费者,消息的接收者,会一直等待消息到来

Queue:消息队列,接收消息缓存消息

Exchange:交换机(X),一方面,接收生产者发送的消息,另一方面知道如何处理消息,例如递交给某个特定的队列、递交给所有队列、或者将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下三种类型:

​ Fanout:广播,将消息交给所有绑定到交换机的队列

​ Direct:定向,将消息交给符合指定routing key 的队列

​ Topic:通配符,将消息交给符合 routing pattern的队列

Exchange(交换机),只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失。

Routing 路由模式

1、模式说明

image-20201208155234165

队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)

消息的发送方向Exchange发送消息时,也必须指定消息的Routingkey

Exchange不在把消息交给每一个绑定的队列,而是根据消息的RoutingKey进行判断,只有队列的RoutingKey与消息的Routingkey完全一致,才会接收到消息

Topics通配符模式

1、模式说明

image-20201208160930053

2、小结

Topic的主题模式可以实现Pub/Sub发布与订阅模式和Routing路由模式的功能,只是Topic在配置routing key的时候可以使用通配符,显得更加灵活。

四Spring Boot 整合MQ

image-20201208175003947

五 RabbitMQ高级特性

5.1消息的可靠性投递

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

​ confirm确认模式

​ return退回模式

rabbitmq的整个消息投递的路径:Producer--》rabbitmq broker--》exchange--》queue--》consumer

​ 消息从producer到exchange则返回一个confirmCallback

​ 消息从exchange到queue投递失败则会返回一个returnCallback

我们将利用着两个callback控制消息的可靠性投递

SpringBoot代码实现

更改配置开启confirm及return模式

spring:
  rabbitmq:
    host: 172.21.194.194
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    publisher-confirms: true ## 开启confirm
    publisher-returns: true ## 开启return

小结

image-20201210131231846

5.2Cosumer Ack

ack指Acknowledge确认,表示消费端收到消息后的确认方式。

三种确认方式:

​ 自动确认:acknowledge=”none“

​ 手动确认:acknowledge=”manual“

​ 根据异常情况确认:acknowledge=”auto"(这种方式使用麻烦不做讲解)

其中自动确认是指,当消息一旦被consumer接收到,则自动确认收到,并将相应message从RabbitMQ的消息缓存中删除。但在实际的业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会消失,如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAck(),手动签收,若出现异常则调用channel.basicNack(),让他自动重新发送消息。

Spring Boot代码实现

​ 配置信息

spring:
  rabbitmq:
    host: 172.21.194.194
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: manual

5.3消费端限流

consumer限流机制

​ 1 确保ack机制为手动确认

​ 2、配置属性perfetch拉取消息的最大数目

​ perfetch=1,表示消费端每次从MQ拉取一条消息来消费,直到手动确认消费完毕后,才会自动拉取下一条消息

Spring Boot代码实现

配置信息

spring:
  rabbitmq:
    host: 172.21.194.194
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      simple:
        acknowledge-mode: manual ##配置手动签收
        prefetch: 1 ##设置每次拉取消息数目

5.4TTL

TTL全称 Time To Live(存活时间/过期时间)

当消息到达存活时间后,还没有被消费,则被自动清除

RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间

image-20201210143734632

小结

设置队列的过期时间使用参数:x-message-ttl。单位ms (毫秒 )会对整个队列的消息统一过期

设置消息过期时间使用参数:expiration。单位ms(毫秒),当该消息在队列的头部时(消费时),会单独判断消息是否过期

如果两者都进行了设置,以时间短的为准

5.5死信队列

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

image-20201210151713464

消息成为死信的三种情况

1队列消息长度到达限制

2消费者拒接消费信息,basicNack/basicReject,并且不把消息重新放入原目标队列,require=false

3原队列存在消息过期设置,消息到达超时时间未被消费

队列绑定死信交换机

给队列设置参数:x-dead-letter-exchange,x-dead-letter-routing-key

image-20201210152408385

小结

死信交换机和死信队列与普通的没有区别

当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列

成为死信的三种情况,见上述

5.6延迟队列

延迟队列,即消息进入队列后不会立即被消费,只有达到指定的时间,才会被消费

需求

​ 1下单后,30分钟未支付,取消订单,回滚库存

​ 2 新用户注册7天后,发送短信问候

实现方式

​ 定时器

​ 延时队列

image-20201210155757468

很可惜在RabbitMQ中未提供延迟队列的功能

但是可以使用:TTL+死信队列组合实现延时队列的效果

image-20201210155923597

### 小结

延迟队列指消息进入队列后,可以被延迟一段时间,再进行消费

RabbitMQ没有提供延迟队列的功能,但是可以使用TTL+DLX来实现死信队列的效果

5.7日志与监控

5.8消息追踪

消息追踪-Firehose

消息追踪-rabbitmq_tracing

六应用问题

RabbitMQ的应用问题

​ 1消息的可靠性保障:消息补偿机制

image-20201210171101118

​ 2消息幂等性保障:乐观锁解决方案

image-20201210171406075

七集群搭建

镜像队列

负载均衡Haproxy

image-20201210172507201

posted @ 2021-12-22 11:40  地球小星星  阅读(147)  评论(0)    收藏  举报