单台emqx 5.0.24社区版,客户端连接断开自动重连,丢消息

EMQX 版本

EMQX 5.0.24

EMQX 集群情况

单节点

服务器操作系统和平台

CentOS 7.9

测试机器硬件配置

8核 24GB,11th Gen Intel(R) Core™ i7-1195G7 @ 2.90GHz 2.92 GHz

测试工具

paho_cs_sub:订阅和打印消息

在 EMQX 中启用的功能

启用了 HTTP 认证

测试场景

1>使用paho_cs_sub连接broker,cleansession设置为false,等待几秒,然后断开
2>在测试机发起 MQTT over TCP 连接,以 100~300/s 的速率写入10万条消息(QoS=0)到指定的TOPIC
3>在测试再次启动paho_cs_sub连接broker,连接成功,开始打印消息。只收到部分消息。系统检测到连接拥塞。跟踪日志显示连接断开,内容如下。

具体问题

测试程序收到消息只有打印,但实际应用收到消息之后有调用其他耗时操作。在测试机只收到部分消息。感觉和客户端消费能力有关,消费速度慢,断开的早,消费速度快,断开的晚。只要消费速度慢,早晚断开连接。

几个疑问点需要明确一下:

  1. 1> 中 “使用 paho_cs_sub 连接” 的客户端 clientid 是什么,是 tester1
  2. 2> 中 “测试机发起 MQTT over TCP” 连接的 clienttid 是什么,也是 tester1 ?这里日志中的 disconnect 和 connection_terminate 原因都是 takenover
  3. 只收到部分消息指 10w 条消息中的一部分?是在 10w 条消息都发完了才开始 3> 中的操作的么?还是说在发送 10w 条消息过程中启动了 paho_cs_sub ,只收到了连接上之后的消息?

还请详细描述一下 pub/sub 流程的细节

步骤#1,2,clientid和user1相同,都是tester1。先写完10w条消息,再启动。
1>paho_cs_sub->broker, 其中cleansession=false,并订阅4668成功。paho_cs_sub退出。
2>给4668发送10w条消息,qos=0,发送程序退出。
3>paho_cs_sub->broker, 其中cleansession=false,并订阅4668成功。接收数据,只能收到部分数据。连接断开。系统告警提示有拥塞。

连接是被服务器主动关闭的?怎么配置才能接收到所有数据?

paho_cs_sub 客户端使用 cleansession=false, clientid=tester1 连接(mqttv3)并订阅主题 4668
pub 客户端使用相同 clientid=tester1 连接,如果也指定 cleansession=false 连接,会继续使用 paho_cs_sub 创建的 session, 仍然具有对 4668 的订阅,此时 pub 客户端 publish 的消息会被它自己收到。
请尝试使用两个不同的 clientid 进行测试。

此外,配置项 mqtt.max_mqueue_len 默认为 1000, mqtt.mqueue_store_qos0 默认为 true
所以在默认配置下,如果没有 qos1 或 qos2 的消息,只会存储 1000 条 qos0 消息。不建议将 mqtt.max_queue_len 设置的的过大,如您的测试所见,1000 条左右的 qos0 消息已经会导致连接拥塞,过大的 mqueue len 毫无意义。

建议通过对系统内的主题设计进行优化,避免同一主题下有过多消息,这可能导致订阅者收到太多消息出现连接拥塞情况。

生成者是另一个程序,但主题还是4668,qos=0。消费者paho_cs_sub,测试过程中,两次连接,第1次是为了留下会话,第2次是接收数据。

在增大max_mqueue_len的情况下( mqtt.mqueue_store_qos0 默认为 true 保持不变),数据被服务器快速发送到客户端。这里是否可以考虑做限流,就像流入限制一样。

但是发布者使用了同样的 clientid,代表着这个发布者在 EMQX 看来也订阅了 4668 这个主题。请使用不同的 clientid 来进行测试。
关于流控,请参考文档 速率限制

发布者使用不同的clientid=test,之前没有提到。
我们有这个场景,希望大量缓存qos0消息(比如10w),服务器内存足够用。期望消费者能全部接收数据,不能出现连接被关闭等异常。