MQTT 消息过期时间(Message Expiry Interval)
一、是什么
消息过期时间是 MQTT 5.0 引入的一个属性,用来给消息设置一个“保质期”。如果消息在服务器上停留的时间超过了这个期限,服务器就会把它丢弃,不再投递给订阅者。
二、解决什么问题
在 MQTT 的持久会话中,服务器会为离线的客户端缓存消息,等客户端重连后再发送。但如果客户端离线时间太长,有些消息可能已经“过时”了。比如你给朋友发了一条“今晚一起吃饭”,结果朋友三天后才看到,这条消息早就没意义了。消息过期机制就是为了避免发送这些无用的旧消息,节省网络带宽和客户端的处理资源。
三、怎么工作
发布者在发布消息时,可以在 PUBLISH 报文里附带一个 Message Expiry Interval,单位是秒。如果不设置,消息就永不过期。
如果消息在服务器上排队等待投递的时间超过了这个间隔,服务器就会丢弃它。
当服务器转发这条消息时,会更新间隔的值。比如发布时设了30秒,在服务器上待了20秒后才转发,那么订阅者收到的消息里,这个值会变成剩余的10秒。
四、和 Redis 过期时间的区别
本质上是一样的思路:给消息设一个“保质期”,到期就自动删除。
但有一点区别值得注意。Redis 的过期时间通常是从设置的那一刻开始倒计时,时间一到,key 就被删了。
MQTT 的消息过期时间是在消息投递过程中持续倒计时的。具体来说,消息发布时设一个过期时间,比如30秒。消息在 Broker 上排队等待投递,每过一秒,剩余时间就少一秒。如果30秒内成功投递给了订阅者,消息就完成使命了,过期时间不再起作用。如果30秒后还没投递出去,Broker 就把它丢弃。
所以可以理解成:Redis 的过期是“存储层面的过期”,MQTT 的消息过期是“投递层面的过期”。核心思路一样,但倒计时的起点和场景不同。
五、和 Keep Alive、Will Delay 的区别
| 概念 | 管什么 | 谁设置 | 生效时机 |
|---|---|---|---|
| Keep Alive | 连接是否活着 | 客户端 | 连接存续期间 |
| Will Delay Interval | 遗嘱消息延迟多久发 | 客户端 | 异常断开后 |
| Message Expiry Interval | 消息本身还能活多久 | 发布者 | 消息在服务端排队/存储期间 |
三者作用的对象完全不同:Keep Alive 管连接,Will Delay 管遗嘱,Message Expiry 管消息本身。
六、和保留消息的关系
保留消息默认是永久存储的,除非你主动发空消息去清除它。但如果给一条保留消息设置了消息过期时间,服务器就会在到期后自动删除它,这比手动清理更方便。
七、打个比方
你点了一份外卖,商家做好了放在取餐台上。如果5分钟内没人来取,外卖就凉了,商家直接倒掉。这个“5分钟”就是消息过期时间。外卖就是消息,取餐台就是 Broker,来取餐的人就是订阅者。时间一到还没人取,消息就作废了。
八、一句话总结
消息过期时间就是给消息设一个保质期,到期还没投递出去就被服务器丢弃。它和 Redis 的过期时间思路一样,区别在于 MQTT 是在投递过程中持续倒计时,而不是从设置那一刻开始倒计时。