categories: MQ
— RabbitMQ 学习笔记
RPC主要基于TCP/UDP协议,HTTP协议是应用层协议,是构建在传输层协议TCP之上的,RPC效率更高,RPC长连接:不必每次通信都像HTTP一样三次握手,减少网络开销;
HTTP服务开发迭代更快:在接口不多,系统与系统之间交互比较少的情况下,HTTP就显得更加方便;相反,在接口比较多,系统与系统之间交互比较多的情况下,HTTP就没有RPC有优势。
分布式同步通信的问题
电商项目中,如果后台添加商品信息,该信息放到数据库。我们同时,需要更新搜索引擎的倒排索引同时,假如有商品页面的静态化处理,也需要更新该页面信息
归根到底,是同步调用处理不当。这个问题在分布式架构中尤为严重。
消息中间件也可以称消息队列,是指用高效可靠的消息传递机制进行与平台无关的数据交流,并基于数据通信来进行分布式系统的集成。通过提供消息传递和消息队列模型,可以在分布式环境下扩展进程的通信
消息中间件就是在通信的上下游之间截断:break it,Broker 然后利用中间件解耦、异步的特性,构建弹性、可靠、稳定的系统。
异步处理、流量削峰、限流、缓冲、排队、最终一致性、消息驱动等需求的场景都可以使用消息中间件
RabbitMQ
RabbitMQ开始是用在电信业务的可靠通信的,也是少有的几款支持AMQP协议的产品之一。
优点:
轻量级,快速,部署使用方便
支持灵活的路由配置。RabbitMQ中,在生产者和队列之间有一个交换器模块。根据配置的路
由规则,生产者发送的消息可以发送到不同的队列中。路由规则很灵活,还可以自己实现。
- RabbitMQ的客户端支持大多数的编程语言。
缺点:
如果有大量消息堆积在队列中,性能会急剧下降
RabbitMQ的性能在Kafka和RocketMQ中是最差的,每秒处理几万到几十万的消息。如果应
用要求高的性能,不要选择RabbitMQ。
- RabbitMQ是Erlang开发的,功能扩展和二次开发代价很高。
RabbitMQ工作流程详解
生产者发送消息的流程
生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)
生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等
生产者声明一个队列井设置相关属性,比如是否排他、是否持久化、是否自动删除等
生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来
生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息
相应的交换器根据接收到的 routingKey 查找相匹配的队列。
如果找到,则将从生产者发送过来的消息存入相应的队列中。
如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者
关闭信道。
关闭连接。
消费者接收消息的过程
消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作
等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
消费者确认( ack) 接收到的消息。
RabbitMQ 从队列中删除相应己经被确认的消息。
关闭信道。
关闭连接。
RabbitMQ TTL 机制 死信队列 延迟队列
RabbitMQ 可以对消息和队列两个维度来设置TTL。
任何消息中间件的容量和堆积能力都是有限的,如果有一些消息总是不被消费掉,那么需要有一种过期的机制来做兜底。
目前有两种方法可以设置消息的TTL。
通过Queue属性设置,队列中所有消息都有相同的过期时间。
对消息自身进行单独设置,每条消息的TTL 可以不同。
如果两种方法一起使用,则消息的TTL 以两者之间较小数值为准。通常来讲,消息在队列中的生存时间一旦超过设置的TTL 值时,就会变成“死信”(Dead Message),消费者默认就无法再收到该消息。当然,“死信”也是可以被取出来消费的
一般 固定时长 用TTL+死信队列 比如 订单取消
延迟消息是指的消息发送出去后并不想立即就被消费,而是需要等(指定的)一段时间后才触发消费。
可以使用rabbitmq_delayed_message_exchange插件实现。
这里和TTL方式有个很大的不同就是TTL存放消息在死信队列(delayqueue)里,二基于插件存放消息在延时交换机里(x-delayed-message exchange)。