new URI(zk_servers_1) 路径包含下划线无法获取host的问题

45次阅读

共计 3308 个字符,预计需要花费 9 分钟才能阅读完成。

spring cloud gateway 使用 zookeeper 作为注册中心调用其它服务的时候报了下面这个错误:
ava.lang.NullPointerException: null
at 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 配置的名称,空指针异常跟踪发现是下面这个问题导致的:
// 类 HttpClientOptions
public 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 配置就行了。

正文完
 0