RabbitMQ 队列

236 阅读4分钟

目标:RabbitMQ 队列

分析:

RabbitMQ 队列.png

详解:

第一部分 过期时间TTL

TTL,Time to Live 的简称,即过期时间。RabbitMQ可以对消息和队列设置TTL。 目前,设置TTL有以下2种方法:

  • 通过队列属性设置,队列中的所有消息都有相同的过期时间。
  • 对消息本身设置,每条消息的TTL可以不同。 如果同时使用,以TTL较小的那个数值为准。
1、设置队列的TTL
  • x-message-ttl 参数,单位毫秒。定义队列时设置。控制队列中消息是否被自动删除。
    • 如果不设置TTL,则表示此消息不会过期。
    • 如果设置TTL=1000,表示消息1秒后过期。
    • 如果设置TTL=0,则表示除非此时可以直接将消息投递到消费者,否则该消息会被立即丢弃。(immediate 参数在投递失败时会用Basic.Return将消息返回,注意,它们是不同的)
  • x-expires 参数,单位毫秒。定义队列时设置。控制队列是否被自动删除。
    • 如果不设置TTL,则表示此队列不会过期。
    • 如果设置TTL=1000,表示1秒之内未被使用则被删除。
    • 不能设置为0。(队列刚设置就删除,是没有意义的操作)
2、设置消息的TTL
  • expiration 参数,单位毫秒。创建消息推送时设置。
3、队列的TTL与消息的TTL的不同
  • 队列的TTL中的消息,一旦消息过期,就会从队列中删除。
  • 消息的TTL,即使消息过期,也不会马上从队列中抹去,因为每条消息是否过期是在即将投递到消费者之前判定的。 为什么这两种方法处理的方式不一样?因为第一种方法里,队列中已过期的消息肯定在队列的头部,RabbitMQ 只要定期从队头开始扫描是否有过期的消息即可。而第二种方法里,每条消息的过期时间不同,如果要删除所有过期消息势必要扫描整个队列,所以不如等到此消息即将被消费时再判定是否过期,如果过期再进行删除即可。

第二部分 死信队列

DLX,全称 Dead-Letter-Exchange,可以称之为死信交换机,也有人称之为死信邮箱。当消息在一个队列中变成死信(dead message)之后,它能被重新被发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列。

消息变成死信一般是由于以下几种情况:

  • 消息被拒绝(Basic.Reject/Basic.Nack),并且设置 requeue 参数为 false;
  • 消息过期;
  • 队列达到最大长度。 DLX也是一个正常的交换器,和一般的交换器没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。当这个队列中存在死信时,RabbitMQ 就会自动地将这个消息重新发布到设置地 DLX 上去,进而被路由到另一个队列,即死信队列。可以监听这个队列中的消息以进行相应的处理,这个特性与将消息的 TTL 设置为 0 配合使用可以弥补 immediate 参数的功能。
1、设置 DLX
  • x-dead-letter-exchange 参数。定义队列时设置。绑定死信队列。
  • x-dead-letter-routing-key 参数。定义队列时设置。指定路由键,如果没有设定,使用原队列的路由键。
2、应用
  • 消息被拒绝,记录异常分析异常。
  • 消息过期 + DLX,延迟队列。

第三部分 延迟队列

延迟队列存储的对象是对应的延迟消息,所谓“延迟消息”是指当消息被发送以后,并不想让消费者立刻拿到消息,而是等待特定时间后,消费者才能拿到这个消息进行消费。

延迟队列的使用场景有很多,比如:

  • 在订单系统中,一个用户下单之后通常有30分钟的时间进行支付,如果30分钟之内没有支付成功,那么这个订单将进行异常处理,这时就可以使用延迟队列来处理这些订单了。
  • 用户希望通过手机远程遥控家里的智能设备在指定的时间进行工作。这时候就可以将用户指令发送到延迟队列,当指令设置的时间到了再将指令推送到智能设备。
1、实现

消息过期 + DLX。

第四部分 优先级队列

优先级队列,顾名思义,具有高优先级的消息具有高的优先级,优先级高的消息具备优先被消费的特权。

1、设置优先级队列
  • x-max-priority 参数。定义队列时设置。设置队列中消息的最大优先级。默认最小优先级为0。
  • priority 参数。发送消息时设置。