订阅端被动断开连接

背景-做个压力测试,看看服务器订阅端能够每秒消费多少条消息。用程序创建了50个发布者,推送循环推送100次这个消息,消息内容0000000000;111111;1705232417598;666666666666666666666*
服务器java进程里面订阅端消费1000条消息,就会断开连接。
下面是trace的日志
11:59:41.511 [debug] Client(testsub123@42.196.15.192:58268): Shutdown for timeout
11:59:41.511 [info] Session(testsub123): Client <0.1464.313> EXIT for {shutdown,timeout}
11:59:42.077 [debug] Session(testsub123): Resumed by <0.1508.313>
下面是服务端配置信息

{shutdown,timeout} 错误是说发生了 TCP 报文的 timeout,然后断开了 TCP 连接。问题应该发生在你的订阅者客户端上,emqx 给它发送 TCP 报文的时候超时了,最终断开了连接。

问题应该是 TCP 阻塞。你可以通过 netstat -apn 命令观察该订阅者的 TCP 连接状态来确认这个问题,会观察到 TCP buffer (sendq) 增长。

需要提升订阅者处理消息的能力或者使用多个客户端共享订阅,如果当前测试速度是 5000/s 的话,你的订阅者现在处理不了 5000/s 的压力。

感谢您的回复,不过我还是有个疑问-我服务器配置是4核16G内存 3Mbps的配置,而且我订阅端的消息收到后只有打印消息的主题没有其他逻辑,那么我想订阅者处理不了5000/s压力,问题应该不是服务器的配置不够,或者说订阅端处理消息太耗时导致的。
目前个人怀疑问题应该是emq.conf参数配置需要调整,不知道我的分析对不对?另外关于配置参数这块您能给我一些建议么

我觉着没有什么参数要调整,你先使用上面我说的 netstat 命令看看 TCP 连接是不是阻塞了,来确定是不是这个问题。

确实是tcp状态变化了不可用!


我尝试调整了tcp接收和发送缓冲区的最大值,但是没有效果。
sysctl -w net.ipv4.tcp_wmem=“4096 16384 33554432”
sysctl -w net.ipv4.tcp_rmem=“4096 131072 33554432”

没有用的。因为消费速度不够快,不论缓冲区设置多大它早晚是要满的。解决方案是使用共享订阅,或者直接不要用 MQTT订阅,改成使用 Webhook 接收消息。