[翻译]Reactor Netty参考指南 - 6.HTTP客户端

Reactor Netty参考指南目录


原文地址

Reactor Netty提供了易于使用、易于配置的HttpClient。它隐藏了创建HTTP客户端所需的大部分Netty的功能,并增加了Reactive Streams背压。

6.1.连接

要将HTTP客户端连接到给定的HTTP端点,您必须创建并且配置一个HttpClient实例。示例如下:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();  //<1>

        client.get()                       //<2>
              .uri("https://example.com/") //<3>
              .response()                  //<4>
              .block();
    }
}

<1> 创建一个HttpClient实例用来进行的配置操作。

<2> 指定使用GET方法

<3> 指定路径地址

<4> 获取响应HttpClientResponse

下面是使用WebSocket的例子:

https://github.com/reactor/re...

import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import reactor.core.publisher.Flux;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();

        client.websocket()
              .uri("wss://echo.websocket.org")
              .handle((inbound, outbound) -> {
                  inbound.receive()
                         .asString()
                         .take(1)
                         .subscribe(System.out::println);

                  final byte[] msgBytes = "hello".getBytes(CharsetUtil.ISO_8859_1);
                  return outbound.send(Flux.just(Unpooled.wrappedBuffer(msgBytes), Unpooled.wrappedBuffer(msgBytes)))
                                 .neverComplete();
              })
              .blockLast();
    }
}

6.1.1.Host和Port

想要连接指定的host和port,您可以按照如下方式配置HTTP客户端:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .host("example.com") //<1>
                          .port(80);           //<2>

        client.get()
              .uri("/")
              .response()
              .block();
    }
}

<1> 配置HTTP的host

<2> 配置HTTP的port

6.2.预先初始化

默认情况下,HttpClient初始化资源的操作在需要使用的时候才进行。这意味着第一个请求会占用初始化和加载所需的额外时间:

  • 事件循环组
  • 主机名解析器
  • native传输库(当使用了native传输的时候)
  • 用于安全性的native库(使用了OpenSsl的时候)

当您需要预加载这些资源的时候,您可以按照以下方式来配置HttpClient

https://github.com/reactor/re...

import reactor.core.publisher.Mono;
import reactor.netty.ByteBufFlux;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();

        client.warmup() //<1>
              .block();

        client.post()
              .uri("https://example.com/")
              .send(ByteBufFlux.fromString(Mono.just("hello")))
              .response()
              .block(); //<2>
    }
}

<1> 初始化和加载事件循环组,主机名解析器,native传输库和用于安全性的native库

<2> 在发送到第一个请求的时候会进行主机名解析。在这个例子中,使用了一个连接池,所以发送第一个请求的时候就建立了与URL的连接,后续对同一URL的请求就会重复使用池中的连接。

6.3.写出数据

如果要发送数据到一个已有的HTTP端点,您需要通过send(Publisher)方法提供一个Publisher。默认情况下,对于那些用到了request body的HTTP方法会设置Transfer-Encoding: chunked。如果有必须,可以通过设置Content-Length来禁用掉Transfer-Encoding: chunked。下面是发送hello字符串的例子:

https://github.com/reactor/re...

import reactor.core.publisher.Mono;
import reactor.netty.ByteBufFlux;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();

        client.post()
              .uri("https://example.com/")
              .send(ByteBufFlux.fromString(Mono.just("hello"))) //<1>
              .response()
              .block();
    }
}

<1> 向给定的HTTP端点发送hello字符串

6.3.1.添加Headers和其他元数据

当您给已连接的客户端发送数据的时候,您可能想发送额外的headers,cookies和其他的元数据。您可以按照如下配置来实现:

https://github.com/reactor/re...

import io.netty.handler.codec.http.HttpHeaderNames;
import reactor.core.publisher.Mono;
import reactor.netty.ByteBufFlux;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .headers(h -> h.set(HttpHeaderNames.CONTENT_LENGTH, 5)); //<1>

        client.post()
              .uri("https://example.com/")
              .send(ByteBufFlux.fromString(Mono.just("hello")))
              .response()
              .block();
    }
}

<1> 设置Content-Length头并且禁用掉Transfer-Encoding: chunked

压缩

您可以开启HTTP客户端的压缩,这意味着需要添加Accept-Encoding请求头。示例如下:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .compress(true);

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

支持自动重定向

您可以通过配置HTTP客户端来开启自动重定向。

Reactor Netty提供了两种不同的策略来实现自动重定向:

  • followRedirect(boolean):指定对与status是301|302|307|308的是否启用HTTP的自动重定向。
  • followRedirect(BiPredicate):如果提供的predicate匹配上了,则启用自动重定向。

下面是使用followRedirect(true)的例子:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .followRedirect(true);

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

6.4.消费数据

如果要接收从已有HTTP端点发过来的数据,您可以使用HttpClient.ResponseReceiver中的方法来实现。下面是使用responseContent方法的例子:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();

        client.get()
              .uri("https://example.com/")
              .responseContent() //<1>
              .aggregate()       //<2>
              .asString()        //<3>
              .block();
    }
}

<1> 从已有的HTTP端点接收数据

<2> 汇总数据

<3> 将数据转成字符串

6.4.1.读取Headers和其他的元数据

当接受从已有HTTP端点发送过来的数据的时候,您可以检查响应头,状态码和其他元数据。您可以使用HttpClientResponse来获取额外的元数据。示例如下:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client = HttpClient.create();

        client.get()
              .uri("https://example.com/")
              .responseSingle((resp, bytes) -> {
                  System.out.println(resp.status()); //<1>
                  return bytes.asString();
              })
              .block();
    }
}

<1> 获取状态码。

6.4.2.HTTP响应解码器

默认情况下,Netty为传入的响应配置了一些限制,例如:

  • 初始行的最大长度。
  • 所有头的最大长度。
  • content或每个chunk的最大长度。

更多信息请查看HttpResponseDecoder

默认情况下,HTTP客户端配置如下:

./../../reactor-netty-http/src/main/java/reactor/netty/http/HttpDecoderSpec.java

public static final int DEFAULT_MAX_INITIAL_LINE_LENGTH = 4096;
public static final int DEFAULT_MAX_HEADER_SIZE         = 8192;
public static final int DEFAULT_MAX_CHUNK_SIZE          = 8192;
public static final boolean DEFAULT_VALIDATE_HEADERS    = true;
public static final int DEFAULT_INITIAL_BUFFER_SIZE     = 128;

./../../reactor-netty-http/src/main/java/reactor/netty/http/client/HttpResponseDecoderSpec.java

public static final boolean DEFAULT_FAIL_ON_MISSING_RESPONSE         = false;
public static final boolean DEFAULT_PARSE_HTTP_AFTER_CONNECT_REQUEST = false;

/**
 * The maximum length of the content of the HTTP/2.0 clear-text upgrade request.
 * By default the client will allow an upgrade request with up to 65536 as
 * the maximum length of the aggregated content.
 */
public static final int DEFAULT_H2C_MAX_CONTENT_LENGTH = 65536;

当您需要改变这些配置的时候,您可以通过如下方式配置HTTP客户端:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .httpResponseDecoder(spec -> spec.maxHeaderSize(16384)); //<1>

        client.get()
              .uri("https://example.com/")
              .responseContent()
              .aggregate()
              .asString()
              .block();
    }
}

<1> 全部头的最大长度为16384。当超过这个值的时候会引发TooLongFrameException

6.5.生命周期回调

下面的生命周期回调用参数是提供给您用来扩展HttpClient的:

Callback Description
doAfterRequest 当请求被发送之后调用。
doAfterResolve 成功解析远程地址后调用。
doAfterResponseSuccess 当响应数据全部被接收之后调用。
doOnChannelInit 在初始化channel的时候调用。
doOnConnect 在channel将要连接的时候调用。
doOnConnected 在channel已经连接上的时候调用。
doOnDisconnected 在channel断开连接之后调用。
doOnError 当请求没有被发送和响应没有被完全接收到的时候调用。
doOnRedirect 当接收到响应头并且将要将请求重定向的时候调用。
doOnRequest 当将要发送请求的时候调用。
doOnRequestError 当请求没有被发送的时候调用。
doOnResolve 在将要解析远程地址的时候调用。
doOnResolveError 在解析远程地址失败的时候调用。
doOnResponse 在接收到响应头之后被调用。
doOnResponseError 在响应没有被完全接收到的时候调用。

下面是使用doOnConnectiondoOnChannelInit回调的例子:

https://github.com/reactor/re...

import io.netty.handler.logging.LoggingHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import reactor.netty.http.client.HttpClient;
import java.util.concurrent.TimeUnit;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .doOnConnected(conn ->
                              conn.addHandler(new ReadTimeoutHandler(10, TimeUnit.SECONDS)))   //<1>
                          .doOnChannelInit((observer, channel, remoteAddress) ->
                              channel.pipeline()
                                     .addFirst(new LoggingHandler("reactor.netty.examples"))); //<2>

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

<1> 在连接之后添加了一个ReadTimeoutHandlerNetty pipeline。

<2> 在初始化channel的时候添加了一个LoggingHandlerNetty pipeline。

6.6.TCP层的配置

当您需要修改TCP层的配置的时候,您可以使用以下代码段来扩展默认的TCP客户端配置(添加一个option,绑定地址等等):

https://github.com/reactor/re...

import io.netty.channel.ChannelOption;
import reactor.netty.http.client.HttpClient;
import java.net.InetSocketAddress;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .bindAddress(() -> new InetSocketAddress("host", 1234))
                          .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000);

        String response =
                client.get()
                      .uri("https://example.com/")
                      .responseContent()
                      .aggregate()
                      .asString()
                      .block();

        System.out.println("Response " + response);
    }
}

更多关于TCP层的配置请查看TCP Client

6.6.1.Wire Logger

Reactor Netty提供了线路记录(wire logging)用来检查点对点的流量。默认情况下,线路记录是关闭的。如果想要开启它,您必须将日志reactor.netty.http.client.HttpClient的设置为DEBUG等级并且按如下方式进行配置:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .wiretap(true); //<1>

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

<1> 开启线路记录

默认情况下,线路记录在输出内容的时候会使用AdvancedByteBufFormat#HEX_DUMP。您也可以通过配置HttpClient改为AdvancedByteBufFormat#SIMPLE或者AdvancedByteBufFormat#TEXTUAL

https://github.com/reactor/re...

import io.netty.handler.logging.LogLevel;
import reactor.netty.http.client.HttpClient;
import reactor.netty.transport.logging.AdvancedByteBufFormat;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .wiretap("logger-name", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL); //<1>

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

<1> 开启线路记录并使用AdvancedByteBufFormat#TEXTUAL来输出内容。

6.7.SSL和TLS

当您需要使用SSL或者TLS的时候,可以使用下面列出来方式进行配置。默认情况下,如果OpenSSL可用的话,则使用SslProvider.OPENSSL。否则使用SslProvider.JDK。可以通过SslContextBuilder或者设置-Dio.netty.handler.ssl.noOpenSsl=true来进行切换:

https://github.com/reactor/re...

import io.netty.handler.ssl.SslContextBuilder;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();

        HttpClient client =
                HttpClient.create()
                          .secure(spec -> spec.sslContext(sslContextBuilder));

        client.get()
              .uri("https://example.com/")
              .response()
              .block();
    }
}

6.7.1.服务器名称标识

默认情况下,HTTP客户端将远程主机名作为SNI服务器名发送。当您需要修改默认设置的时候,您可以通过如下方式配置HTTP客户端:

https://github.com/reactor/re...

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import reactor.netty.http.client.HttpClient;

import javax.net.ssl.SNIHostName;

public class Application {

    public static void main(String[] args) throws Exception {
        SslContext sslContext = SslContextBuilder.forClient().build();

        HttpClient client =
                HttpClient.create()
                          .secure(spec -> spec.sslContext(sslContext)
                                              .serverNames(new SNIHostName("test.com")));

        client.get()
              .uri("https://127.0.0.1:8080/")
              .response()
              .block();
    }
}

6.8.重试策略

默认情况下,如果请求在TCP层被中断了HTTP客户端会重试一次。

6.9.HTTP/2

默认情况下,HTTP客户端支持HTTP/1.1。如果您需要HTTP/2,您可以通过配置来实现。除了协议配置外,如果您需要H2而不是H2C明文)的话,还必须配置SSL。

由于JDK8不支持 "开箱即用 "的应用层协议协商(ALPN)(尽管一些厂商将ALPN移植到JDK8),您需要添加额外的本地库依赖来支持它,例如: netty-tcnative-boringssl-static

下面列出了一个简单的H2的例子:

https://github.com/reactor/re...

import io.netty.handler.codec.http.HttpHeaders;
import reactor.core.publisher.Mono;
import reactor.netty.http.HttpProtocol;
import reactor.netty.http.client.HttpClient;
import reactor.util.function.Tuple2;

public class H2Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .protocol(HttpProtocol.H2) //<1>
                          .secure();                 //<2>

        Tuple2 response =
                client.get()
                      .uri("https://example.com/")
                      .responseSingle((res, bytes) -> bytes.asString()
                                                           .zipWith(Mono.just(res.responseHeaders())))
                      .block();

        System.out.println("Used stream ID: " + response.getT2().get("x-http2-stream-id"));
        System.out.println("Response: " + response.getT1());
    }
}

<1> 配置客户端仅支持HTTP/2

<2> 配置SSL

6.9.1.选择协议

./../../reactor-netty-http/src/main/java/reactor/netty/http/HttpProtocol.java

public enum HttpProtocol {

    /**
     * The default supported HTTP protocol by HttpServer and HttpClient
     */
    HTTP11,

    /**
     * HTTP/2.0 support with TLS
     * 

If used along with HTTP/1.1 protocol, HTTP/2.0 will be the preferred protocol. * While negotiating the application level protocol, HTTP/2.0 or HTTP/1.1 can be chosen. *

If used without HTTP/1.1 protocol, HTTP/2.0 will always be offered as a protocol * for communication with no fallback to HTTP/1.1. */ H2, /** * HTTP/2.0 support with clear-text. *

If used along with HTTP/1.1 protocol, will support H2C "upgrade": * Request or consume requests as HTTP/1.1 first, looking for HTTP/2.0 headers * and {@literal Connection: Upgrade}. A server will typically reply a successful * 101 status if upgrade is successful or a fallback HTTP/1.1 response. When * successful the client will start sending HTTP/2.0 traffic. *

If used without HTTP/1.1 protocol, will support H2C "prior-knowledge": Doesn't * require {@literal Connection: Upgrade} handshake between a client and server but * fallback to HTTP/1.1 will not be supported. */ H2C }

6.10.度量

HTTP客户端支持与Micrometer的内置集成。它暴露了所有前缀为reactor.netty.http.client的度量。

下面的表格提供了HTTP客户端度量的相关信息:

度量名称 类型 描述
reactor.netty.http.client.data.received DistributionSummary 收到的数据量,以字节为单位
reactor.netty.http.client.data.sent DistributionSummary 发送的数据量,以字节为单位
reactor.netty.http.client.errors Counter 发生的错误数量
reactor.netty.http.client.tls.handshake.time Timer TLS握手所花费的时间
reactor.netty.http.client.connect.time Timer 连接远程地址所花费的时间
reactor.netty.http.client.address.resolver Timer 解析远程地址所花费的时间
reactor.netty.http.client.data.received.time Timer 接收传入数据所花费的时间
reactor.netty.http.client.data.sent.time Timer 传出数据所花费的时间
reactor.netty.http.client.response.time Timer 请求/响应的总时间

下面额外的度量也是可用的:

池化的ConnectionProvider度量

度量名称 类型 描述
reactor.netty.connection.provider.total.connections Gauge 所有连接的数,包括活跃的和空闲的
reactor.netty.connection.provider.active.connections Gauge 已经被成功获取了并且正在使用的连接数
reactor.netty.connection.provider.idle.connections Gauge 空闲的连接数
reactor.netty.connection.provider.pending.connections Gauge 正在等待可用连接的请求数

ByteBufAllocator度量

度量名称 类型 描述
reactor.netty.bytebuf.allocator.used.heap.memory Gauge 堆内存的字节数
reactor.netty.bytebuf.allocator.used.direct.memory Gauge 堆外内存的字节数
reactor.netty.bytebuf.allocator.used.heap.arenas Gauge 堆内存的个数(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.direct.arenas Gauge 堆外内存的个数(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.threadlocal.caches Gauge threadlocal的缓存数量(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.tiny.cache.size Gauge 微小缓存的大小(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.small.cache.size Gauge 小缓存的大小(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.normal.cache.size Gauge 一般缓存的大小(当使用PooledByteBufAllocator的时候)
reactor.netty.bytebuf.allocator.used.chunk.size Gauge 一个区域的块大小(当使用PooledByteBufAllocator的时候)

下面是开启集成的度量的例子:

https://github.com/reactor/re...

import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.config.MeterFilter;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        Metrics.globalRegistry //<1>
               .config()
               .meterFilter(MeterFilter.maximumAllowableTags("reactor.netty.http.client", "URI", 100, MeterFilter.deny()));

        HttpClient client =
                HttpClient.create()
                          .metrics(true, s -> {
                              if (s.startsWith("/stream/")) { //<2>
                                  return "/stream/{n}";
                              }
                              else if (s.startsWith("/bytes/")) {
                                  return "/bytes/{n}";
                              }
                              return s;
                          }); //<3>

        client.get()
              .uri("https://httpbin.org/stream/2")
              .responseContent()
              .blockLast();

        client.get()
              .uri("https://httpbin.org/bytes/1024")
              .responseContent()
              .blockLast();
    }
}

<1> 设置带有URI标签的仪表的上限

<2> 在可能的情况下,模板化的URI将被用作URI标签的值。

<3> 启用内置集成的Micrometer

为了避免启用度量而造成的内存和CPU的开销,如果可以的话,将真实的URI转换为模板化的URI是很重要的。如果不转换为类似于模板的形式,则会导致每一个不同的URI都会创建一个不同的标签,这样度量会占用大量的内存。

始终对带有URI标签的仪表设置一个上限。给仪表配置一个上线以防真实的URI不能被模板化。您可以在maximumAllowableTags找更多的信息。

如果您想让HTTP客户端度量与除了Micrometer之外的系统集成或者想提供自己与Micrometer的集成来添加自己的度量记录器,您可以按如下方式实现:

https://github.com/reactor/re...

import reactor.netty.channel.ChannelMetricsRecorder;
import reactor.netty.http.client.HttpClient;

import java.net.SocketAddress;
import java.time.Duration;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .metrics(true, CustomHttpClientMetricsRecorder::new); //<1>

        client.get()
              .uri("https://httpbin.org/stream/2")
              .response()
              .block();
    }

}

<1> 开启HTTP客户端度量并且提供HttpClientMetricsRecorder的实现。

6.11.Unix域套接字

当使用本地传输时,HTTP客户端支持Unix域套接字(UDS)。

下面是使用UDS的例子:

https://github.com/reactor/re...

import io.netty.channel.unix.DomainSocketAddress;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .remoteAddress(() -> new DomainSocketAddress("/tmp/test.sock")); //<1>

        client.get()
              .uri("/")
              .response()
              .block();
    }
}

<1> 指定将使用的DomainSocketAddress

6.12.主机名解析

默认情况下,HttpClient使用Netty的域名查询机制来异步解析域名。用来替代JVM内置阻塞解析器。

当您需要修改默认设置的时候,您可以像如下通过配置HttpClient来实现:

https://github.com/reactor/re...

import reactor.netty.http.client.HttpClient;

import java.time.Duration;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .resolver(spec -> spec.queryTimeout(Duration.ofMillis(500))); //<1>

        String response =
                client.get()
                      .uri("https://example.com/")
                      .responseContent()
                      .aggregate()
                      .asString()
                      .block();

        System.out.println("Response " + response);
    }
}

<1> 解析器每次执行DNS查询的超时时间设置为500ms。

下面的列表展示了可用的配置:

配置名称 描述
cacheMaxTimeToLive DNS资源记录缓存的最大存活时间(单位:秒)。如果DNS服务器返回的DNS资源记录的存活时间大于这个最大存活时间。该解析器将忽略来自DNS服务器的存活时间,并使用这个最大存活时间。默认为Integer.MAX_VALUE
cacheMinTimeToLive DNS资源记录缓存的最小存活时间(单位:秒)。如果DNS服务器返回的 DNS 资源记录的存活时间小于这个最小存活时间,则此解析器将忽略来自DNS服务器的存活时间并使用这个最小存活时间。默认:0。
cacheNegativeTimeToLive DNS查询失败的缓存时间(单位:秒)。默认:0。
disableOptionalRecord 禁用自动包含的可选设置,该设置会试图告诉远程DNS服务器解析器每次响应可以读取多少数据。默认情况下,该设置为启用状态。
disableRecursionDesired 用于指定该解析器在查询DNS的时候会不会带上期望递归查询(RD)的标志,默认情况下,该设置为启用状态。
maxPayloadSize 设置数据报包缓冲区的容量(单位:字节)。 默认:4096
maxQueriesPerResolve 设置解析主机名允许发送的最大DNS查询次数。默认:16
ndots 设置在进行初始化绝对查询的时候,名称中必须出现的点的数量。默认值:-1(用于判断Unix操作系统的值,否则使用1)。
queryTimeout 设置该解析器每次DNS查询的超时时间(单位:毫秒)。默认:5000
resolvedAddressTypes 解析地址的协议族列表。
roundRobinSelection 启用DnsNameResolverAddressResolverGroup,用于当命名服务器提供了多个地址的时候支持随机选择目标地址。参见RoundRobinDnsAddressResolverGroup。默认:DnsAddressResolverGroup
runOn 在给定的LoopResources上执行与DNS服务器的通信。默认情况下,LoopResources只在客户端上被使用。
searchDomains 解析器的搜索域列表。默认情况下,有效搜索域列表是使用的系统DNS搜索域。
trace 在解析器在解析失败时生成详细的跟踪信息时使用的日志记录器和日志级别。

有时候,您或许想切换为JVM内建的解析器。您可以通过如下配置HttpClient的方式来实现:

https://github.com/reactor/re...

import io.netty.resolver.DefaultAddressResolverGroup;
import reactor.netty.http.client.HttpClient;

public class Application {

    public static void main(String[] args) {
        HttpClient client =
                HttpClient.create()
                          .resolver(DefaultAddressResolverGroup.INSTANCE); //<1>

        String response =
                client.get()
                      .uri("https://example.com/")
                      .responseContent()
                      .aggregate()
                      .asString()
                      .block();

        System.out.println("Response " + response);
    }
}

<1> 设置为JVM内建的解析器。

Suggest Edit to "HTTP Client"


Reactor Netty参考指南目录


版权声明:如需转载,请带上本文链接、注明来源和本声明。否则将追究法律责任。 https://www.immuthex.com/posts/reactor-netty-reference-guide/http-client

你可能感兴趣的:([翻译]Reactor Netty参考指南 - 6.HTTP客户端)