emqx离线订阅消息失败问题排查

最近在工作中发现一个问题,记录一下这个问题的排查过程及解决方案。

问题背景:

项目使用emqx作为消息中间件,中转平台和车端消息。车端离线后,平台发起一个远控命令,首先会对车机进行唤醒,车端被唤醒后,按理应该就能消费emqx里的离线消息(远控命令)。但是车端目前的反馈是被唤醒后有的时候能收到,有的时候收不到。平台下发唤醒命令后,几百ms内就会将远控命令发到emqx,车端收到唤醒后,大概2s作用会去订阅相关topic。

分析思路:

1.订阅不到消息可能性之一就是消息被丢弃了,如果订阅者没有设置持久会话(也就是clean session=false),那么设备在离线后,会话被删除,消息发布后,因为没有订阅者,就会立马被丢弃。但是经排查,平台和车端都是设置了持久会话,因此这个分析结果不成立。还有一种可能就是消息等级设置的不够高也会导致消息丢失,

MQTT 定义了三个 QoS 等级,分别为:

  • QoS 0,最多交付一次。
  • QoS 1,至少交付一次。
  • QoS 2,只交付一次。

其中,使用 QoS 0 可能丢失消息,使用 QoS 1 可以保证收到消息,但消息可能重复,使用 QoS 2 可以保证消息既不丢失也不重复。但是排查后,车端和平台也都是设置qos2,因此这个推测也不成立。

2.emqx的消息默认是存在内存队列中的,队列默认值是1000,可设置存在内存或者硬盘,或者内存加硬盘,存在硬盘中是为了做持久化,防止消息因服务器重启丢失。如果队列中消息超过设置的最大值,那么新来的消息会把之前的消息替换掉,遵循先进先出原则。目前验证这个推测,只能通过emqx提供的日志追踪功能去排查,通过监控topic和客户端,查看消息具体丢失原因。

eqmx控制台配置日志追踪:

 配置好日志追踪后,车子休眠一段时间再次唤醒,发送消息,发现还是订阅不到平台下发的消息,查看下发这条消息日志追踪的topic,发现下发消息的topic里并没有这个车子的订阅,所以肯定消费不到,平台下发唤醒车子,然后大概几百ms发送远控命令消息到emqx,车子收到短信唤醒指令后,大概要2s时间才能连上emqx,也就是说车子连上emqx之前,消息已经发到emqx,此时车端如果没有做持久会话,就没有订阅关系,所以消息会直接丢弃。因此车端连上emqx后还是消费不到消息,因此还是持久会话没有设置好,翻看官方文档,持久会话不仅要设置clean session =false,这只是开关,还有会话时间也要设置,默认的是2h,超过2h会话就没有了,为了印证这个问题,我们把车子离线时间设置在会话过期时间内唤醒,经过测试发现是可以消费到消息的,找到问题所在,会话时间可以根据业务需求设置,当然emqx也提供了更好的方案去解决这个问题,它提供了离线消息通过规则引擎,保存到redis,mysql等数据库中,支持持久化。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值