MAC电脑RocketMQ发送客户端启动后发送第一条消息老是报sendDefaultImpl call timeout???

前言

之前,有业务侧同学第一次在自己项目上集成RocketMQ时,在自己电脑上测试的时候,一发送消息就报错sendDefaultImpl call timeout,然后反馈过来看是什么原因,我仔细查了下原因,结果很讶异,过程也很有趣,就顺便记录下发现的过程和原因。

环境

RocketMQ4.7.1

java版本消息发送客户端

现象

启动发送端,发送消息,报错:

过程

当时看到这个异常的第一反应是:他是不是在压测或者是网络问题,然后确认了下,没有压测,就是在自己电脑上发条消息试下。查看了下服务器端,此时也没有任何压力,也就是服务器、客户端此时没有性能压力。我随即确认了下网络也是正常的,即使网速一般,发条消息也是没问题的。默认超时时间是3s。

同事说是网络问题,办公网有点差,让他们调大超时时间, 对这个说法,我觉得不太靠谱。

因为第一次发送出现这个异常,之后发消息就正常了。 然后看了下这个异常,抛出的地方,在org.apache.rocketmq.client.impl.producer.DefaultMQProducerImpl#sendDefaultImpl方法:

有个callTimeout判断,,,callTimeout为什么会true呢,

原来是还没发送就超时了。

RocketMQ的发送超时设置的不单是底层TCP的读取超时,这个时间还包括发送前代码处理耗时,这样的处理地方有很多,可以说它的时延低就离不开这各处细节的优化控制,包括broker端。

既然是这样,猜测,第一次发送前是否是初始化占用了太多耗时,然后想了想前几年用的时候,也没遇到过这种问题呀,然后把客户端从启动到发送这里的代码捋了几遍,确认在当前场景下,没有可能出现特别耗时的地方。

然后越来越奇怪了,没有办法我就在自己猜测可能出现耗时的地方埋点,计算调用耗时,最后,发现问题出在这个地方:

进入这个方法体内特别耗时:

MAC电脑RocketMQ发送客户端启动后发送第一条消息老是报sendDefaultImpl call timeout???_第1张图片

猜测是不是涉及的某些类初始化特别慢,只能打印类加载的初始化信息,然后,还真的发现有这个问题:

MAC电脑RocketMQ发送客户端启动后发送第一条消息老是报sendDefaultImpl call timeout???_第2张图片

耗时达到了5s,我是花了不少时间跟踪,然后,我从代码跟,最终是找到初始化特别慢的地方了,在MessageClientIDSetter的静态初始化块里调用:UtilAll.getPid()方法,一跟代码往下跟,最后走到这里:

MAC电脑RocketMQ发送客户端启动后发送第一条消息老是报sendDefaultImpl call timeout???_第3张图片

有经验的老司机已经看出问题了,

如果不想继续往下跟,最笨的办法是:发送消息前,可以先调用下MessageClientIDSetter的createUniqID()方法,主要目的是先完成这个类的初始化就没问题了。

继续调代码,问题在这里:

MAC电脑RocketMQ发送客户端启动后发送第一条消息老是报sendDefaultImpl call timeout???_第4张图片

这是一个native方法,我翻了下open jdk的源码,没找到实现,很尴尬。

解决

这是/etc/hosts文件配置的问题,类似的问题可以上网上搜下,最后说下根本解决办法,因为公司统一配置的是mac pro,所以说的是mac os,执行如下命令,设置一下hostname:

scutil --set HostName 'localhost'

 

你可能感兴趣的:(消息,------》RocketMQ,rocketmq,call,timeout)