生产环境偶尔出现消息丢失问题,emqx收到先是收到消息(第一条日志),后推送到对应的主题中(第二条日志),正常没有丢失情况会出现第三条日志客户端会收到消息,偶尔会出现没有第三条日志情况数据就丢失了,请问下下原因以及排查方向
第一条日志:
2025-03-26T12:20:41.590038+08:00 [debug] clientid: , line: 781, mfa: emqx_connection:handle_incoming/2, msg: mqtt_packet_received, packet: PUBLISH(Q1, R0, D0),Topic=, PacketId=272Payload={ xxxx}, peername: 172.16.0.113:64960, tag: MQTT
第二条日志:
2025-03-26T12:20:41.591668+08:00 [debug] clientid: , line: 73, mfa: emqx_trace:publish/1, msg: publish_to, payload: { xxxxx}, peername: 172.16.0.113:64960, tag: PUBLISH, topic:
第三条日志:
2025-03-26T12:25:42.729310+08:00 [debug] clientid: , line: 827, mfa: emqx_connection:serialize_and_inc_stats_fun/1, msg: mqtt_packet_sent, packet: PUBLISH(Q1, R0, D0),Topic=, PacketId=6925Payload={ xxxx }, peername: 172.16.0.241:37084, tag: MQTT
一个 no subscriber 就是你 clean start = true 登录的订阅端,离线了,就会直接丢弃掉消息。
一个 queue_full 大概率就是你 clean start=false( 小概率也有可能是true)的订阅端的 queue 满 了,一个订阅端收的消息太多了,处理不过来,就直接丢弃掉了。再加上你的告警提示,应该就是一个订阅端的压力太大,被断开后又重连。导致的。
有什么优化方案吗
使用共享订阅来分担压力。
为了确保系统稳定性和消息传输的可靠性,建议每个订阅客户端的消息接收速率不超过 1500 消息/秒(按每条消息 1KB 计算)。
如果消息接收速率超过此建议,可以使用共享订阅来添加多个订阅客户端,从而分散负载,降低单个订阅客户端的消息接收速率。
实在没有办法做大的修改,而且丢弃只是峰值时短暂发生的话,可以尝试适当去增加 MQTT 设置中的最大消息队列长度,默认是 1000 的。别设置太大,消息累积多了会把内存挤爆的。
现在就是使用的共享订阅,那只能修改队列长度了吗
不建议改长度,多加几个订阅端会更好
已经扩了客户端了,现在客户端扩到5个了,还是很频繁的出现这个问题
加多少个是可以估算出来的。
可以算一下平均一个订阅端的 QPS 是多少,文档说的是最好在 1500 以下,也是假设订阅端使用的异步处理消息的方法。如果订阅端使用的是同步处理消息(先处理完上一个消息,才会去接收下一个消息),这种同步也得改改。
订阅端是异步处理的,现在每五分钟上报一次,同时有4万左右的数据上来,那需要20个节点才行吗,订阅段压力太大会被断开,这个压力多少界限才会被断开
是的 大概需要多少订阅端才行呢
对的,你已经算出来了,当然这些都是经验值,你还是得实际测。
至少这么看,你的 5 个是绝对不够的。
好的 谢谢