Netty with ReactorClient TTPConnector:如何设置readTimeout、writeTimeout和connectTimeout,而不使用不推荐的TCPC配置

Netty with ReactorClient TTPConnector:如何设置readTimeout、writeTimeout和connectTimeout,而不使用不推荐的TCPC配置,netty,spring-webflux,Netty,Spring Webflux,Netty不赞成使用HttpClient\tcpConfiguration。我们正在寻找一种简单的方法来配置: connectTimeout:等待连接的时间 WriteMout:写入流的等待时间(如果在此时间范围内无法传递数据,将引发异常) readTimeout:从流中读取的等待时间(如果在此时间范围内未传递数据,将引发异常) 当前代码如下所示: HttpClient-HttpClient=HttpClient.create(); 整数connecttimeoutims=clientPro

Netty不赞成使用
HttpClient\tcpConfiguration
。我们正在寻找一种简单的方法来配置:

  • connectTimeout:等待连接的时间
  • WriteMout:写入流的等待时间(如果在此时间范围内无法传递数据,将引发异常)
  • readTimeout:从流中读取的等待时间(如果在此时间范围内未传递数据,将引发异常)
当前代码如下所示:

HttpClient-HttpClient=HttpClient.create();
整数connecttimeoutims=clientProperties.getConnectTimeoutims();
整数WriteTimeoutims=clientProperties.GetWriteTimeoutims();
Integer readTimeout=clientProperties.GetReadTimeOutims();
httpClient=httpClient.tcpConfiguration(tcpClient-RAM->{
TcpClient TcpClient=TCPClientRAM;
//连接超时配置
if(connecttimeoutims!=null){
tcpClient=tcpClient.option(ChannelOption.CONNECT\u TIMEOUT\u MILLIS,connecttimeoutims);
}
返回tcpClient.doOnConnected(连接->{
if(readTimeout!=null){
conn.addHandlerLast(新的ReadTimeoutHandler(readTimeout,TimeUnit.millides));
}
if(writeTimeoutims!=null){
conn.addHandlerLast(新的WriteTimeoutHandler(WriteTimeOutItems,TimeUnit.毫秒));
}
});
});
在不使用tcpConfiguration的情况下应该如何配置?以下方法未按预期工作,并且未按预期引发ReadTimeout

Integer readTimeout=clientProperties.getreadtimeoutims();
if(readTimeout!=null){
httpClient.doOnConnected(c->c.addHandlerLast(新的ReadTimeoutHandler(readTimeout,TimeUnit.millides));
}
整数WriteTimeoutims=clientProperties.GetWriteTimeoutims();
if(writeTimeoutims!=null){
httpClient.doOnConnected(
c->c.addHandlerLast(新的WriteTimeoutHandler(WriteTimeOutItems,TimeUnit.millides));
}
整数connectTimeout=clientProperties.GetConnectTimeOutims();
if(connectTimeout!=null){
选项(ChannelOption.CONNECT\u TIMEOUT\u MILLIS,connectTimeout);
}

正确的实施方式是什么?我看到Netty提供了
HttpClient#responseTimeout()
,它最终设置了
HttpClientOperations#addHandler(nettypeline.ResponseTimeoutHandler,新的ReadTimeoutHandler(responseTimeout.toMillis(),TimeUnit.mills))。但是没有连接或写入的方法。

这可以通过反应器连接提供程序和一对Netty处理程序的组合来完成。我正在使用注入WebClient.Builder的基本Spring配置bean,如下所示:

import java.time.Duration;
import java.util.concurrent.TimeUnit;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Bean;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;

import io.netty.channel.ChannelOption;
import io.netty.handler.timeout.ReadTimeoutHandler;
import io.netty.handler.timeout.WriteTimeoutHandler;
import reactor.netty.Connection;
import reactor.netty.ConnectionObserver;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

public class WebClientFactory implements ConnectionObserver {
    private final Logger LOG = LogManager.getLogger(getClass());
    private final int connectTimeout;
    private final long readTimeout;
    private final long writeTimeout;
    private final int maxConnections;
    private final Duration maxAcquireTime;
    private final Duration maxIdleTime;
    private final Duration maxLifeTime;
    
    
    private final WebClient.Builder webClientBuilder;

    /**
     * Creates a new WebClientFactory
     * @param config The web client configuration
     */
    public WebClientFactory(WebClientConfiguration config) {
        connectTimeout = config.getConnectTimeout();
        readTimeout = config.getReadTimeout();
        writeTimeout = config.getWriteTimeout();
        maxConnections = config.getMaxConnections();
        maxAcquireTime = Duration.ofMillis(config.getMaxAcquireTime());
        maxIdleTime = Duration.ofMillis(config.getMaxIdleTime());
        maxLifeTime = Duration.ofMillis(config.getMaxLifeTime());
        ConnectionProvider connectionProvider =
                ConnectionProvider.builder("aod-http-client")
                        .maxConnections(maxConnections)
                        .pendingAcquireTimeout(maxAcquireTime)
                        .maxIdleTime(maxIdleTime)
                        .maxLifeTime(maxLifeTime)
                        .build();
        HttpClient httpClient = HttpClient.create(connectionProvider)
                .doOnConnected(conn -> conn
                        .addHandlerLast(new ReadTimeoutHandler(readTimeout, TimeUnit.MILLISECONDS))
                        .addHandlerLast(new WriteTimeoutHandler(writeTimeout, TimeUnit.MILLISECONDS))
                 ).option(ChannelOption.CONNECT_TIMEOUT_MILLIS, connectTimeout)             
                .observe(this);
        webClientBuilder = WebClient.builder()
                .clientConnector(
                        new ReactorClientHttpConnector(httpClient)
                            
                );
                
        LOG.info("WebClientConfig: connectTimeout={}, readTimeout={}, writeTimeout={}", connectTimeout, readTimeout, writeTimeout);
    }
    
    @Bean
    protected WebClient.Builder webClientBuilder() {
        return webClientBuilder;
    }

    /**
     * @see reactor.netty.ConnectionObserver#onStateChange(reactor.netty.Connection, reactor.netty.ConnectionObserver.State)
     */
    @Override
    public void onStateChange(Connection connection, State newState) {
        LOG.info("WebClient State Change: connection={}, newState={}", connection, newState);       
    }
    
    /**
     * @see reactor.netty.ConnectionObserver#onUncaughtException(reactor.netty.Connection, java.lang.Throwable)
     */
    @Override
    public void onUncaughtException(Connection connection, Throwable error) {
        LOG.error("WebClient Uncaught Exception: connection={}", connection, error);        
    }

}

除此之外,Spring参考文档还包含设置最常用超时设置的推荐方法: