java如何處理localhost這個主機名的?
調試一個wsl2+java引發的bug
最近聽說wsl2將要在2004穩定可用,於是就趕了時髦在使用了wsl+docker部署了數據庫和nacos等等東西,將原來使用虛擬機的容器都遷移過去
這遷移後就出了問題,目前(2020 04 16)wsl2是無法自定義ip地址,但是之前的版本更新已經可以將localhost的請求轉發到wsl2裡面去
當我部署完nacos之後,使用瀏覽器訪問localhost:8848是沒有問題的 但是問題就在於java客戶端死活連接不上,java客戶端使用的主機名就是localhost,報的是connection refuse
調試JDK源碼
但是當我使用了wsl2內部提供的地址之後,socket連接成功了
<code>Socket socket =new
Socket("localhost"
,8848
); Socket socket =new
Socket("127.0.0.1"
,8848
); Socket socket =new
Socket("172.30.39.169"
,8848
); /<code>
既然wsl官方都宣稱可以使用localhost訪問了,而且瀏覽器也確實可以訪問
那麼問題既有可能出現在java對localhost的解析上面
調試JDK源碼發現,JDK 的InetAddress使用這段代碼將主機名轉為ip地址
<code>try
{
addresses
=nameService.lookupAllHostAddr(host);
catch (UnknownHostException uhe) {
if
(host.equalsIgnoreCase("localhost")) {
addresses
=new InetAddress[] { impl.loopbackAddress() };
}
else
{
ex
=uhe;
}
}
/<code>
而這個loopbackAddress翻譯過來就是計算機網絡中的迴環地址,我們點進去
<code>public
synchronized
InetAddressloopbackAddress
()
{if
(loopbackAddress ==null
) {byte
[] loopback = {0x7f
,0x00
,0x00
,0x01
}; loopbackAddress =new
Inet4Address("localhost"
, loopback); }return
loopbackAddress; } /<code>
<code>byte
[] loopback = {0x7f
,0x00
,0x00
,0x01
} /<code>
這個玩意轉換成十進制就是127.0.0.1
那麼我們直接在windows使用這個ip是訪問不到wsl2的
解決
那麼是不可能修改JDK源碼的
也不知道wsl以後的更新會不會解決這個問題
目前一個的辦法就是直接使用wsl2的內部ip地址:172.30.39.169 所以目前JAVA需要直接直接使用這個ip連接
但是這個ip一旦機器重啟就會發生改變,我們的微服務項目又很多
只能採取一個折中的方案,定義一個host映射 local–>172.30.39.169