我有vertx HttpClient的问题。 这里的代码显示了使用vertx和普通java进行测试。
Vertx vertx = Vertx.vertx();
HttpClientOptions options = new HttpClientOptions()
.setTrustAll(true)
.setSsl(false)
.setDefaultPort(80)
.setProtocolVersion(HttpVersion.HTTP_1_1)
.setLogActivity(true);
HttpClient client = vertx.createHttpClient(options);
client.getNow("google.com", "/", response -> {
System.out.println("Received response with status code " + response.statusCode());
});
System.out.println(getHTML("http://google.com"));
getHTML()来自此处:How do I do a HTTP GET in Java?
这是我的输出:
<!doctype html><html... etc <- correct output from plain java
Feb 08, 2017 11:31:21 AM io.vertx.core.http.impl.HttpClientRequestImpl
SEVERE: java.net.UnknownHostException: failed to resolve 'google.com'. Exceeded max queries per resolve 3
但是vertx无法连接。这有什么不对?我没有使用任何代理。
答案 0 :(得分:1)
供参考:this question和tsegismont的注释中所述的解决方案是将标志vertx.disableDnsResolver
设置为true
:
-Dvertx.disableDnsResolver=true
为了以explained here的身份回退到JVM DNS解析器:
有时可能需要使用JVM内置的解析器,JVM系统属性-Dvertx.disableDnsResolver = true会激活此行为
我在kubernetes环境中观察到了Redis客户端的DNS解析问题。
答案 1 :(得分:1)
我遇到了这个问题,对我来说是由Java运行时获取了过时的DNS服务器,即为计算机不再连接的网络注册的服务器。问题首先出现在Sun JNDI实现中,Netty也存在该问题,Netty使用JNDI在大多数平台上引导其名称服务器列表,然后最终在VertX中显示。
我认为解决此问题的一个好地方是在Netty层中引导默认DNS服务器集。我已经为Netty项目筹集了入场券,所以我们看看他们是否同意! Here is the Netty ticket
同时,一个相当基本的解决方法是根据是否可访问来过滤Netty检测到的默认DNS服务器。这是Kotlin中的代码示例,可在构造主要VertX实例之前应用。
// The default set of name servers provided by JNDI can contain stale entries
// This default set is picked up by Netty and in turn by VertX
// To work around this, we filter for only reachable name servers on startup
val nameServers = DefaultDnsServerAddressStreamProvider.defaultAddressList()
val reachableNameServers = nameServers.stream()
.filter {ns -> ns.address.isReachable(NS_REACHABLE_TIMEOUT)}
.map {ns -> ns.address.hostAddress}
.collect(Collectors.toList())
if (reachableNameServers.size == 0)
throw StartupException("There are no reachable name servers available")
val opts = VertxOptions()
opts.addressResolverOptions.servers = reachableNameServers
// The primary Vertx instance
val vertx = Vertx.vertx(opts)
更多细节,以帮助您。我有一台公司机器,该机器有时通过物理电缆连接到公司网络。公司内部名称服务器的详细信息是通过DHCP在物理接口上设置的。使用在家中的无线接口,无线接口的DNS设置为我的家庭DNS,而物理接口的配置未更新。很好,因为该设备未处于活动状态,ipconfig / all不显示内部公司DNS服务器。但是,在注册表中查看它们仍然存在:
计算机\ HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters \ Interfaces
它们由JNDI机制处理,该机制为Netty和VertX提供了支持。由于无法从我的家庭位置访问它们,因此DNS解析失败。我可以想象这种家庭/办公室情况并非我独有!我不知道容器或VM上的多个虚拟接口是否会发生类似的情况,如果您遇到问题,值得一看。
答案 2 :(得分:0)
以下是适用于我的示例代码。
public class TemplVerticle extends HttpVerticle {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
// Create the web client and enable SSL/TLS with a trust store
WebClient client = WebClient.create(vertx,
new WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
.setDefaultHost("www.w3schools.com")
);
client.get("www.w3schools.com")
.as(BodyCodec.string())
.send(ar -> {
if (ar.succeeded()) {
HttpResponse<String> response = ar.result();
System.out.println("Got HTTP response body");
System.out.println(response.body().toString());
} else {
ar.cause().printStackTrace();
}
});
}
}
答案 3 :(得分:0)
尝试使用Web客户端而不是httpclient,在这里有一个示例(带有rx):
private val client: WebClient = WebClient.create(vertx, WebClientOptions()
.setSsl(true)
.setTrustAll(true)
.setDefaultPort(443)
.setKeepAlive(true)
)
open fun <T> get(uri: String, marshaller: Class<T>): Single<T> {
return client.getAbs(host + uri).rxSend()
.map { extractJson(it, uri, marshaller) }
}
另一个选择是使用getAbs。