spring cloud gateway使用zookeeper作為注冊中心調用其它服務的時候報了下面這個錯誤:
ava.lang.NullPointerException: nullat io.netty.util.NetUtil.isValidIpV4Address(NetUtil.java:648) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]at io.netty.util.NetUtil.createByteArrayFromIpAddressString(NetUtil.java:368) ~[netty-common-4.1.29.Final.jar:4.1.29.Final]at reactor.ipc.netty.options.InetSocketAddressUtil.attemptParsingIpString(InetSocketAddressUtil.java:132) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]at reactor.ipc.netty.options.InetSocketAddressUtil.createForIpString(InetSocketAddressUtil.java:80) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]at reactor.ipc.netty.options.InetSocketAddressUtil.createInetSocketAddress(InetSocketAddressUtil.java:69) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]at reactor.ipc.netty.options.ClientOptions.createInetSocketAddress(ClientOptions.java:253) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]at reactor.ipc.netty.http.client.HttpClientOptions.getRemoteAddress(HttpClientOptions.java:87) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]at reactor.ipc.netty.http.client.MonoHttpClientResponse.lambda$subscribe$0(MonoHttpClientResponse.java:76) ~[reactor-netty-0.7.10.RELEASE.jar:0.7.10.RELEASE]
調用的地址是http://zks_servers_1:18001,zks_servers_1是服務的hosts配置的名稱,空指針異常跟蹤發現是下面這個問題導致的:
//類HttpClientOptionspublic final InetSocketAddress getRemoteAddress(URI uri) {Objects.requireNonNull(uri, "uri");boolean secure = isSecure(uri);int port = uri.getPort() != -1 ? uri.getPort() : (secure ? 443 : 80);boolean shouldResolveAddress = !this.useProxy(uri.getHost());return this.createInetSocketAddress(uri.getHost(), port, shouldResolveAddress);}
uri.getHost()返回值是null,也就是說根據上面的調用地址,沒有獲取到對應的host。
uri的創建方式是:
//類MonoHttpClientResponse
MonoHttpClientResponse(HttpClient parent, String url, HttpMethod method, Function<? super HttpClientRequest, ? extends Publisher<Void>> handler) {this.parent = parent;boolean isWs = Objects.equals(method, HttpClient.WS);try {this.startURI = new URI(parent.options.formatSchemeAndHost(url, isWs));} catch (URISyntaxException var7) {throw Exceptions.bubble(var7);}this.method = isWs ? HttpMethod.GET : method;this.handler = handler;}
創建方式是調用URI的new URI(String)方法,知道原因之后在本地測試:
try {URI uri = new URI("http://zks_servers_1:18001/test.html");String host = uri.getHost();System.out.println(host);} catch (URISyntaxException e) {e.printStackTrace();}
確實獲取不到host,查看源碼發現:
/*** Returns the host component of this URI.** <li><p> A domain name consisting of one or more <i>labels</i>* separated by period characters ({@code '.'}), optionally followed by* a period character. Each label consists of <i>alphanum</i> characters* as well as hyphen characters ({@code '-'}), though hyphens never* occur as the first or last characters in a label. The rightmost* label of a domain name consisting of two or more labels, begins* with an <i>alpha</i> character. </li>* </ul>** The host component of a URI cannot contain escaped octets, hence this* method does not perform any decoding.** @return The host component of this URI,* or {@code null} if the host is undefined*/public String getHost() {return host;}
谷歌翻譯:
由一個或多個標簽組成的域名由句點字符代碼'.'分隔,可選地后跟一個英文句號角色。 每個標簽由alphanum字符組成以及連字符字符代碼' - ',雖然連字符永遠不會作為標簽中的第一個或最后一個字符出現。 最右邊包含最少長度最少兩個并且以英文字符開始的標簽
舉例如下:
www.baidu.com,這個域名包含三個標簽www、baidu、com;
www.baidu-zhidao.com,這個域名包含三個標簽www、baidu-zhidao、com;
這個例子就是說明每個標簽都可以使用-連接;
然后看一下,我的報錯的服務名稱zks_servers_1,這個名稱沒有以【.】分割,包含了非法字符【_】最后以單個數字結尾也不符合要求。
實際上測試發現zks-servers-1這樣也是不正確的,不知道是不是翻譯的有問題,這個結果和翻譯不太匹配。
總而言之,修改服務器的hosts配置就行了。