Vertx HttpClient getNow无效

时间:2017-02-08 10:37:14

标签: java http vert.x vertx-httpclient

我有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无法连接。这有什么不对?我没有使用任何代理。

4 个答案:

答案 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。