客户端链接在,但是订阅的消息不定期丢

我使用的服务器版本4.4.11. 下端的客户端刚链接的时候正常链接,订阅正常,但是不定期的就会发生链接在但是所订阅的topic没有了,从监控看这个客户端没有订阅任何topic。这是不可能的。下端的客户端重启一下,从新链接之后能正常一会,不定期的还掉。现在不知道什么原因,也不知道怎么去排查这个问题。请佬教我

订阅不会自动丢失,你可以检查一下是不是连接有中断,客户端重连后没有重新订阅

这个断开链接事件我哪里可以看见?不会看

一般客户端库会有连接断开的回调,或者你可以在EMQX用日志追踪功能追踪一下你的客户端

就是这个不会,官方有教程?

找到教程了,我尝试一下

1 个赞

检测到一条异常数据2024-06-01T16:22:16.604158+08:00 [info] MzE2NzczMDQ4NDMwMDYwNzY0NzU1MzQ5Mzc3OTUwMDIzNjI@192.168.33.158:44294 MzE2NzczMDQ4NDMwMDYwNzY0NzU1MzQ5Mzc3OTUwMDIzNjI SUBSCRIBE $IOT/business/car/0003010000000100: Options: #{nl => 0,qos => 2,rap => 0,rh => 0,sub_props => #{}}这之后就丢了,我不知道上述日志代表什么,也不知道引起故障的逻辑

这条日志是说 clientid 为MzE2NzczMDQ4NDMwMDYwNzY0NzU1MzQ5Mzc3OTUwMDIzNjI 的客户端在192.168.33.158的机器上通过 44294 的端口,订阅了$IOT/business/car/0003010000000100 的主题。他的订阅参数是#{nl => 0,qos => 2,rap => 0,rh => 0,sub_props => #{}}。

  1. 这不是一条异常日志。并不会引起描述中的全部topic丢失。
  2. 以经验下看,大概率客户端因为什么原因有重连了,可以重点针对 clientid 做 trace。看他是不是有 2 次 connect 包,或者出现问题的过程中他的连接端口是否发生变化 变化(即重连了)后是否有重新订阅的逻辑。

1D5.zip (493.5 KB)
上传了一下日志追踪,我真不会看问题,请教我,抱拳抱拳


你的客户端代码重连有问题:
日志里面一共有237 次重连:CONNECT,而且使用的都是 clean_start=true,但是连上来再次订阅的只有1 次。其它的 236 次都没有订阅,所以是收不到消息,只是连上来在发消息。
图里面就是那唯一的一次 subscribe。

重连的原因有233次 tcp_closed 和 4 次 keepalive_timeout。
tcp_closed说明是客户端主动断开的连接。
keepalive_timeout说明是客户端的心跳跑超时了没有发过来。
建议仔细检查一下客户端的重连代码。

我的使用逻辑是有一个长时间链接等待订阅信息的。发送数据的链接是使用一次链接一次,发送完就断开,不占用资源。所以导致上述情况,但是你说的clean_start=true 这个是啥意思呢?并且我以上的使用逻辑是否符合设计要求呢?

推荐你通读一下 MQTT 协议,或者看看 emqx官网推出的 MQTT 白皮书,实在不行就搜索一下 MQTT clean_start.

一般 MQTT 客户端都是保持长连接的。从来不推荐使用一次就断开。而且从你的日志上看:

2024-06-03T11:46:40.033105+08:00 [info] 192.168.33.158:41076     msg: terminate
    reason: {shutdown,tcp_closed}
2024-06-03T11:46:41.414025+08:00 [debug] 192.168.33.158:40038 [Channel] RECV CONNECT(Q0, R0, D0ClientId=00000000000001D5, ProtoName=MQTT, ProtoVsn=4, CleanStart=true, KeepAlive=60, Username=iot_device, Password=******)

11:46:40秒断开,11:46:41 秒就又连上来,完全没有必要。对于 EMQX 来说,维持一个 TCP 长连接,比每次新建一个 TCP 连接消耗少多了。
从日志的场景来看这样设计不合理。

但是我用的开源版本,我看资源是受限制的,连接数量等。想节省点资源

另外我发送重联的时候好像使用了与订阅同一个cleanid,这个是否也受到影响呢

开源版本没有任何连接数限制。
重连就是要用同一个 clientid,否则无法识别为同一个客户端,
真心推荐空闲的时候补一下 mqtt 基础知识。这样以后有设计问题心里有个底。