目标:RabbitMQ 队列
分析:
详解:
第一部分 过期时间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参数。发送消息时设置。