【RocketMQ】服务端错误排查:RemotingTooMuchRequestException/sendSelectImpl call timeout

背景

业务团队在做压测的时候,发现RocketMQ频繁报错,大致信息如下:

sendSelectImpl call timeout; nested exception is org.apache.rocketmq.remoting.exception.RemotingTooMuchRequestException: sendSelectImpl call timeout

问题排查

由异常的字面信息,怀疑是并发过高,导致服务端负载太大,导致请求处理不过来了,但是细想,RocketMQ的TPS单机是几万,集群是3主6从,也就是TPS可以达到10w左右,不可能业务团队可以承受的TPS,到RocketMQ端处理不过来,所以问题没那么简单,于是打开源码看一下问题出现的原因。源码中出现问题的代码定位如下:

这段代码的逻辑是选择本次消息发送的队列,并发送消息,异常产生的原因是处理超时了,超时时间默认是3s。

也就是说,确实是服务端处理不过来了,有的文章说需要把超时时间设置长一点,但是这治标不治本,并且官方的压测代码,用的都是默认的配置,所以问题并不是修改配置那么简单,还需要进一步探究。

难道说业务团队的程序TPS可以超过10W,力压RocketMQ,虽然有点不敢相信,但是目前只能顺着这个方向去查,想让业务方再进行一次压测,让问题复线一下,但是由于各种原因,无法再进行压测,所以无法复线问题。

于是带着一个疑问去排查:在进行压测的时候,RocketMQ本身的TPS达到了多少?难道真的被打满了吗?

问题定位

只能从RocketMQ本身着手,RocketMQ的Console只能显示一些运行时的信息,无法查看之前的状态,于是登陆到RocketMQ所在的服务器,从日志入手,果然看到有用的信息,服务端的日志有如下:

有一个stats.log,肯定和RocketMQ运行时的各项指标有关系,先tail一下看看有些什么:

可以看到,每隔一段时间,会打印服务端的一些指标,其中就包含了每个Topic的TPS,这对于我来说很有用,下载到本地,用Topic和压测的时间去过滤,发现了如下信息:

业务团队压测时,对应Topic的TPS只有7353、16474,但是有一个系统的Topic:RMQ_SYS_TRACE_TOPIC的TPS达到了将近7W,大大占用了RocketMQ的资源,很明显就是因为这个Topic导致的,而这个Topic是用来做消息追踪的,也就是说用户的客户端开启了消息追踪功能,

问题解决

开启消息追踪功能之后,对用户提交的消息,都会往系统的Topic:RMQ_SYS_TRACE_TOPIC上发送一条,当然内部可能不是同步发送,可能是积攒一定的时间再一起发送,否则TPS也不会瞬间达到6W多,所以如果程序要求高并发,最好不要使用消息追踪功能,否则会影响到性能,解决方法就是把生产者和消费者客户端的enableMsgTrace设置为false:

Producer:

Consumer:

おすすめ

転載: blog.csdn.net/sinat_14840559/article/details/119785997