0%

日常解惑-Springboot启动慢的bug

前情

运行一个springboot的项目,第一行弹出了警告:

1
WARN 69220 --- [  restartedMain] o.s.boot.StartupInfoLogger               : InetAddress.getLocalHost().getHostName() took 5006 milliseconds to respond. Please verify your network configuration (macOS machines may need to add entries to /etc/hosts).

解决办法

可以看到,springboot警告,有一个InetAddress.getLocalHost().getHostName()方法执行了5秒,这太慢了,需要去确认一下网络配置,如果是macOS用户的需要去编辑一下/etc/hosts

看到这个函数其实就知道了,是在获取我的电脑主机名字。那么为什么这个函数会耗时那么久呢?我在自己的idea里面试了一下,运行InetAddress.getLocalHost() 这个方法确实需要5秒。

这个应该是(猜测)会去访问DNS进行解析,但是一般来说个人的主机名字肯定是无法进行解析的,所以当时间到达了上限之后(5秒)就返回了结果。

这个问题解决的话也是很简单的,在macOS上面,只需要在终端中输入hostname就可以看到Mac主机名,然后编辑一下/etc/hosts这个文件,加入这两行即可:

1
2
127.0.0.1   localhost Mac主机名
::1 localhost Mac主机名

然后就可以了。如果发现还是不可以推荐使用dscacheutil -flushcache 并重启Mac。

拓展

macOS中的主机名字

苹果机器有三个名字,分别是:

image-20210810100632213

其中的hostname命令输出的就是上面的HostName。其中一般的终端的提示也是hostname。

而另外两个名字则是在系统设置里面:

image-20210810100940379

图中的电脑名称就是ComputerName,而下面的以.local结尾的则是LocalHostName,Mac会自动加上这个结尾。

如果希望修改这三个名字:

1
2
3
sudo scutil --set ComputerName "newname"
sudo scutil --set LocalHostName "newname"
sudo scutil --set HostName "newname"

把set改成get就可以获取对应的主机名字了(get不需要权限)。

为什么会出现这个问题

其实我之前运行springboot一直好好的,最近在GitHub上面跑一个项目的时候才发现有这个问题。

我在网上搜索了一下,发现确实也有别的网友有这个问题,就是如果你没有手动设置过苹果的hostname,而只是设置了对应的主机名(刚购买的时候利用图形化界面设置的),那么这个hostname是可能会发生改变的,我自己就是hostname发生了变化,导致了/etc/hosts/ 中对应的条目无法生效。网上看到的是如果你的hostname中有除了大小写字母的其它字符(包括.),那么macOS就会帮你修改…

所以推荐使用上面的命令进行hostname的设定,这样就不会改变了。

springboot

在springboot的GitHub的项目下,有一个issue就是这个问题。下面这个回答我觉得很有道理:

When you request a hostname, the JDK resolves it to IP addresses. It then tries a reverse lookup of those addresses and checks that at least one of the results maps back to the input host name. It’s this reverse lookup that’s slow. The slowness isn’t limited to the JVM. Anything on the OS that tries to perform such a reverse lookup will be slow without appropriate configuration in /etc/hosts.

JDK会把hostname解析成IP地址(可能会有多个),并且它会去确认至少其中一个IP地址能够重新映射回hostname,正是这个从IP再解析回hostname的过程非常慢。所以需要配置对应的映射文件,来进行加速

Ref