RabbitMQ 学习笔记


categories: MQ
— RabbitMQ 学习笔记

RPC主要基于TCP/UDP协议,HTTP协议是应用层协议,是构建在传输层协议TCP之上的,RPC效率更高,RPC长连接:不必每次通信都像HTTP一样三次握手,减少网络开销;

HTTP服务开发迭代更快:在接口不多,系统与系统之间交互比较少的情况下,HTTP就显得更加方便;相反,在接口比较多,系统与系统之间交互比较多的情况下,HTTP就没有RPC有优势。

分布式同步通信的问题

电商项目中,如果后台添加商品信息,该信息放到数据库。我们同时,需要更新搜索引擎的倒排索引同时,假如有商品页面的静态化处理,也需要更新该页面信息

归根到底,是同步调用处理不当。这个问题在分布式架构中尤为严重。

消息中间件也可以称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信

消息中间件就是在通信的上下游之间截断:break it,Broker 然后利用中间件解耦、异步的特性,构建弹性、可靠、稳定的系统。

异步处理流量削峰、限流、缓冲、排队、最终一致性消息驱动等需求的场景都可以使用消息中间件

RabbitMQ

RabbitMQ开始是用在电信业务的可靠通信的,也是少有的几款支持AMQP协议的产品之一。

优点:

  1. 轻量级,快速,部署使用方便

  2. 支持灵活的路由配置。RabbitMQ中,在生产者和队列之间有一个交换器模块。根据配置的路

由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己实现。

  1. RabbitMQ的客户端支持大多数的编程语言。

缺点:

  1. 如果有大量消息堆积在队列中,性能会急剧下降

  2. RabbitMQ的性能在Kafka和RocketMQ中是最差的,每秒处理几万到几十万的消息。如果应

用要求高的性能,不要选择RabbitMQ。

  1. RabbitMQ是Erlang开发的,功能扩展和二次开发代价很高。

RabbitMQ工作流程详解

生产者发送消息的流程

  1. 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)

  2. 生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等

  3. 生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等

  4. 生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来

  5. 生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息

  6. 相应的交换器根据接收到的 routingKey 查找相匹配的队列。

  7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。

  8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者

  9. 关闭信道。

  10. 关闭连接。

消费者接收消息的过程

  1. 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。

  2. 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作

  3. 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。

  4. 消费者确认( ack) 接收到的消息。

  5. RabbitMQ 从队列中删除相应己经被确认的消息。

  6. 关闭信道。

  7. 关闭连接。

RabbitMQ TTL 机制 死信队列 延迟队列

RabbitMQ 可以对消息和队列两个维度来设置TTL

任何消息中间件的容量和堆积能力都是有限的,如果有一些消息总是不被消费掉,那么需要有一种过期的机制来做兜底。

目前有两种方法可以设置消息的TTL。

  1. 通过Queue属性设置,队列中所有消息都有相同的过期时间。

  2. 对消息自身进行单独设置,每条消息的TTL 可以不同。

如果两种方法一起使用,则消息的TTL 以两者之间较小数值为准。通常来讲,消息在队列中的生存时间一旦超过设置的TTL 值时,就会变成“死信”(Dead Message),消费者默认就无法再收到该消息。当然,“死信”也是可以被取出来消费的

一般 固定时长 用TTL+死信队列 比如 订单取消

延迟消息是指的消息发送出去后并不想立即就被消费,而是需要等(指定的)一段时间后才触发消费。

可以使用rabbitmq_delayed_message_exchange插件实现。

这里和TTL方式有个很大的不同就是TTL存放消息在死信队列(delayqueue)里,二基于插件存放消息在延时交换机里(x-delayed-message exchange)。

image-20210126171322013