0%

从Netty的Connect到lookupAllHostAddr

前言

用Netty写一个应用,写到Client端的代码,因为之前的模板都是
ChannelFuture channelFuture = bootstrap.connect().sync();
这个Connect会阻塞在这儿,但是我不想让他阻塞,于是天经地义的写成了

1
2
ChannelFuture channelFuture = bootstrap.connect();
future.complete(channelFuture.channel());

把channel给complete出去。

问题

但是我启动的时候发现还是等待了很久,大概等了5s的时间,找了半天,发现是在bootstrap.connect()这儿阻塞了。
但是当我改成sync()的时候,发现还是阻塞了5s。
这个时候我略崩溃。

然后问郑阿里星这个方法是不是阻塞的,我是不是记错了。
郑阿里星表示他也记得是异步的,不会等很久的。

我又试了几次发现还是如此,郑阿里星表示把代码发给他,他来试一试。

然后奇迹出现了,他只花了300ms。

百思不得其解,为啥我的要5s,他的要300ms。
而且我sync()之后也是5s,大概率认为就是没有异步执行。

无头绪

一开始我觉得可能是线程池的Reject参数,把connect用户线程做了。
于是debug了一下,发现走到了

这确实是走到了异步的执行里面啊。

肯定就是中间的哪个部分出现了问题。

定位

这时候郑阿里星提供了144.144.144.144这个地址让我试试,我发现还是5s。
这个时候基本就是我的电脑的问题,不会是Netty代码的问题了。
因为这个就算是sync()的也不会是5s的时间。

不说了,先重启再说。

重启完毕,再执行,还是5s。

好吧,有点崩溃。

我开个热点,连自己热点看看,
然后奇迹出现了,时间变成了300ms,变正常了。

肯定就是中间的网哪儿的问题啊。

5s的时间,也不短,我索性把线程全部dump出来,看看main线程block在哪儿了。

1
$ jstack -l `jps | grep Test | awk -F' ' '{print $1}'`

多试了几次,发现了关键。

发现都是在java.net.Inet6AddressImpl.lookupAllHostAddr这个方法里。

去谷歌一搜,似乎真的发现了几个issue。

Netty Issue

连block的秒数都和我一样,真的是天才。

解决方案

去搜寻了一番,找到了解决办法,修改hosts文件,加上下面两行。

1
2
127.0.0.1 zhuyichendeMacBook-Pro.local
::1 zhuyichendeMacBook-Pro.local