# hosts 文件中添加主机名times=1789ip addresss: 127.0.0.1
可以看到,当 hosts 文件中没有添加主机名时,根本找不到对应的网络地址(因为 dns 中也没有解析到),添加之后就能返回对应的 ip 127.0.0.1 了 。
这里有几个地方需要注意:
- 即使 hosts 文件中添加主机名,标准 Linux 的 getaddrinfo 方法执行时,也会有接近两秒的耗时,但我们在 Java 代码中运行时却只有几十毫秒;
- 前文我们使用 Wireshark 抓包时提到,mdns 查询时存在重试机制,但标准 Linux 的 getaddrinfo 方法中没有看到对应的代码;
- 前面提到的5秒返回结果,其实不是返回结果,而是超时了 。但标准 Linux 的 getaddrinfo 方法中没有看到对应的超时控制代码;
接着上面的第3点,回到 Java 项目调试一下,看看为什么超时了还能返回结果 。
当 hosts 文件中没有添加主机名时,会返回本机所有的 ip 地址:

文章插图
当 hosts 文件中添加主机名后,只会返回配置的 127.0.01 的 ip 地址:

文章插图
其中,当 hosts 文件中没有添加主机名时,getaddrinfo 调用返回错误码,此时 jdk 会转而调用 lookupIfLocalhost 方法,它内部调用了操作系统的 getifaddrs 方法,以获取本机所有 ip 地址:

文章插图

文章插图
对应的源码可以参考https://codebrowser.dev/glibc/glibc/sysdeps/unix/sysv/linux/ifaddrs.c.html 。
总结本文以 Java 中获取主机名慢的场景为契机,使用多种技术手段研究背后的原理,包括使用 Wireshark 抓包,使用 Arthas 工具定位到性能瓶颈,再转到 jdk 中查看对应的 native 方法实现,由于没找到最底层调用链路源码,转而参照标准Linux的相关源码,简单复现了上述场景 。
进一步地,由于没找到最底层调用链路源码,我们根据现象猜测的本地缓存、重试、超时等机制没有得到验证,有兴趣的同学可以进一步研究探索 。
参考文章
如何查找 jdk 中的 native 实现【InetAddress.getLocalHost 执行很慢?】
从Chrome源码看DNS解析过程
getaddrinfo工作原理分析
浅谈getaddrinfo函数的超时处理机制
经验总结扩展阅读
- 如何通过执行SQL为低代码项目提速?
- 手机上网很慢怎么处理(怎么样解决手机上网太慢)
- 跳转控制语句break
- 显示器启动很慢怎么回事
- 遗产继承官司判决后如何执行
- 报时机器人的rasa shell执行流程分析
- 工厂想采购一套信息化生产执行系统mes,不知道用哪家比较好?
- 爱情中很慢热的天王星星座有哪些
- 通过Thread Pool Executor类解析线程池执行任务的核心流程
- 电视剧执行利剑小艾结局是什么?