如何为spring-boot-2.1.6的HttpClient/TcpClient设置连接/读写超时?
适配Spring Boot 2.1.6(Reactor Netty 0.8.9.RELEASE)的超时配置方案
一、连接超时配置的正确性修正
你当前的连接超时代码不生效,原因是Reactor Netty的配置类为不可变设计,调用tc.option(...)会返回一个新的TcpClient实例,必须将这个新实例赋值给tc才能让配置生效。修正后的代码如下:
final HttpClient httpClient = HttpClient.create() .tcpConfiguration(tc -> { Optional.ofNullable(getConnectTimeout()) .map(Duration::toMillis) .map(Math::toIntExact) .ifPresent(ct -> { // 必须接收option返回的新实例,否则配置不会生效 tc = tc.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, ct); }); return tc; });
如果是固定时长的配置,可简化为:
final HttpClient httpClient = HttpClient.create() .tcpConfiguration(tc -> tc.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000));
二、写入超时配置
写入超时需在客户端连接建立后添加WriteTimeoutHandler实现,有两种配置方式:
方式1:通过HttpClient的doOnConnected配置
final HttpClient httpClient = HttpClient.create() .doOnConnected(conn -> conn.addHandlerLast(new WriteTimeoutHandler(10, TimeUnit.SECONDS)) );
方式2:通过tcpConfiguration配置TcpClient
final HttpClient httpClient = HttpClient.create() .tcpConfiguration(tc -> tc.doOnConnected(conn -> conn.addHandlerLast(new WriteTimeoutHandler(10, TimeUnit.SECONDS)) ) );
三、读取超时配置
读取超时的配置逻辑与写入超时一致,使用ReadTimeoutHandler即可:
方式1:通过HttpClient的doOnConnected配置
final HttpClient httpClient = HttpClient.create() .doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(15, TimeUnit.SECONDS)) );
方式2:通过tcpConfiguration配置TcpClient
final HttpClient httpClient = HttpClient.create() .tcpConfiguration(tc -> tc.doOnConnected(conn -> conn.addHandlerLast(new ReadTimeoutHandler(15, TimeUnit.SECONDS)) ) );
四、单独使用TcpClient时的超时配置
如果直接使用TcpClient而非HttpClient,配置逻辑完全一致:
// 连接超时 TcpClient tcpClient = TcpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000); // 写入+读取超时 tcpClient = tcpClient.doOnConnected(conn -> { conn.addHandlerLast(new WriteTimeoutHandler(10, TimeUnit.SECONDS)); conn.addHandlerLast(new ReadTimeoutHandler(15, TimeUnit.SECONDS)); });
内容的提问来源于stack exchange,提问作者Jin Kwon
相关产品推荐
相关产品推荐

