Весна 5 webflux как установить тайм-аут на Webclient

Я пытаюсь установить тайм-аут на моем WebClient, вот текущий код:

SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

ClientHttpConnector httpConnector = new ReactorClientHttpConnector(opt -> {
    opt.sslContext(sslContext);
    HttpClientOptions option = HttpClientOptions.builder().build();
    opt.from(option);
});
return WebClient.builder().clientConnector(httpConnector).defaultHeader("Authorization", xxxx)
                .baseUrl(this.opusConfig.getBaseURL()).build();

мне нужно добавить тайм-аут, а также стратегию объединения, Я думал о чем-то вроде этого :

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(this.applicationConfig.getHttpClientMaxPoolSize());
cm.setDefaultMaxPerRoute(this.applicationConfig.getHttpClientMaxPoolSize());
cm.closeIdleConnections(this.applicationConfig.getServerIdleTimeout(), TimeUnit.MILLISECONDS);

RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(this.applicationConfig.getHttpClientSocketTimeout())
        .setConnectTimeout(this.applicationConfig.getHttpClientConnectTimeout())
        .setConnectionRequestTimeout(this.applicationConfig.getHttpClientRequestTimeout()).build();

CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(cm).build();

но я не могу понять, как установить httpClient в моем webclient

3 ответов


В WebFlux WebClient не использует HTTP-клиент Apache Commons. Хотя вы можете реализовать одно решение через custom ClientHttpConnector. Существующее ReactorClientHttpConnector основано на Нетти. Итак, рассмотрите возможность использования параметров Netty для настройки клиента, например:

ReactorClientHttpConnector connector =
            new ReactorClientHttpConnector(options ->
                    options.option(ChannelOption.SO_TIMEOUT, this.applicationConfig.getHttpClientConnectTimeout()));

или

.onChannelInit(channel -> channel.config().setConnectTimeoutMillis(this.applicationConfig.getHttpClientConnectTimeout()))

обновление

мы также можем использовать ReadTimeoutHandler:

.onChannelInit(channel -> 
        channel.pipeline()
           .addLast(new ReadTimeoutHandler(this.applicationConfig.getHttpClientConnectTimeout())))

чтобы установить тайм-аут чтения и подключения, я использую метод ниже, потому что опция SO_TIMEOUT недоступна для каналов, использующих NIO (и дающих предупреждение Unknown channel option 'SO_TIMEOUT' for channel '[id: 0xa716fcb2]')

ReactorClientHttpConnector connector = new ReactorClientHttpConnector(
          options -> options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 2000)
                            .compression(true)
                            .afterNettyContextInit(ctx -> {
                                ctx.addHandlerLast(new ReadTimeoutHandler(5000, TimeUnit.MILLISECONDS));
                            }));
return WebClient.builder()
                .clientConnector(connector)
                .build();

вот как я это сделал (спасибо @Artem)

SslContext sslContext = SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE).build();

        ClientHttpConnector httpConnector = new ReactorClientHttpConnector(options -> {
            options.sslContext(sslContext);
            options.option(ChannelOption.SO_TIMEOUT, this.applicationConfig.getHttpClientRequestTimeout());
            options.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, this.applicationConfig.getHttpClientConnectTimeout());
            options.poolResources(PoolResources.fixed("myPool", this.applicationConfig.getHttpClientMaxPoolSize()));
        });

        return WebClient.builder().clientConnector(httpConnector).defaultHeader("Authorization", "xxxx")
                .baseUrl(this.config.getBaseURL()).build();