RabbitMQ 的 使用总结

MQ的优点

  1. 服务间解耦
  2. 服务的异步调用
  3. 流量削峰

routing key

路由键,负责queue和exchange的绑定关系。消息被投递到exchange后,会根据routing key被投递到一个或多个队列中。

Exchange

交换机,用于接收消息。可以认为是routing key和queue的绑定表。交换机有多个类型。

  1. dirct:直连交换机,根据routing key精确匹配队列投递消息。
  2. Topic:主题交换机,routing key的单词之间使用.隔开;使用通配符“*”匹配两个.之间一个单词,“#”匹配两个.之间多个单词,
  3. Fanout:扇形交换机,将消息投递到所有绑定的queue上。所以这里routing key被忽略
  4. headers:头交换机,根据消息头中的参数将消息投递到对应的交换机,存在与、或两种模式,即a&&b a||b。

他们的投递效率:fanout > dirct > topic > headers.一般headers效率太低不会采用。

queue

消息队列,消息最初由exchange接收消息,并根据消息的routing key转发到队列。customer通过监听队列获取消息。

channel

信道,RabbitMQ采用的是一个TCP连接上建立多个信道的方式来传输消息。

元数据

每个组件存在一些自己的元数据,比如:

  1. queue(名称、routingkey,kv属性,例如x-message-ttl等)
  2. exchange(名称、type类型、kv属性等)
  3. binding(ex routing key queue的绑定关系)

消息状态

  • ready 即可以被消费的消息
  • unacked 即已经被customer消费但尚未进行ack、unack、reject的消息.unack和reject区别:unack支持multiple参数,一次性可以批量处理小于当前ID的所有消息;而reject不支持。

说完基础概念,接下来探讨一下关于消息投递相关的问题

生产者如何保障消息的百分百可靠性投递

rabbitMQ提供了两种方式供producers使用,即事务机制和confirm机制。

事务机制

即在投递消息之前通过channel.txSelect()开启事务。发送结束提交事务txCommit();异常回滚txRollback()。事务方案的效率过低,一般我们不采用这个方案。

confirm机制

发送消息时会给消息一个唯一ID(递增),当确认消息从exchange成功投递到了queue时,回通过回调异步通知producers;如果因为MQ内部报错那么会异步回调一个nack。

顺便再说一下Springboot 使用时的两个回调,confirmCallback和returnCallback

  • 同步确认机制:使用confirm机制,在发送完消息之后,使用channel.waitForConfirms()等待回调。需要配置publisher-confirm-type: simple使用。
  • 异步确认机制:使用回调函数接收回调。publisher-confirm-type: correlated

customer如何确保成功消费

消费者通过channel的ack/nack/reject操作对消息进行消费、拒绝,重新入队等操作。

Ack机制分:

1,自动ACK:默认ack机制。当消息被推送到消费者就认为消费成功。存在处理报错导致数据丢失问题。一般不采用。

2,手动ACK:在代码合适位置手动确认。可以根据业务处理选择ack.或者nack,是否重新入队等操作。

 

认定死信

  1. 消息被拒绝病requeue=false
  2. 消息过期
  3. 队列达到最大长度

队列长度限制

声明队列时可以通过参数设置队列最大长度或者最大byte,当超过最大后,队列会丢弃最老的消息或者转入死信队列

死信队列

当消息被认定为死信时,如果queue配置了x-dead-letter-exchange,将会把死信消息转发到DLX,死信交换机,再根据x-dead-letter-routing-key指定的routingk ey或者queue默认的routing key转发到queue上

延迟队列实现

RabbitMQ不支持延迟队列,但可以通过过期时间+死信队列实现

posted @ 2022-04-13 22:25  大树2  阅读(91)  评论(0编辑  收藏  举报