Задержка запроса Spring WebClient из-за неактивного соединения

Я использую Spring WebClient в своем приложении Spring Boot для вызова внешних API. Приложение работает на JBoss EAP 7.3.x, используется Java 8, Springboot 2.7.1. Я настроил пул соединений для повышения производительности, но столкнулся с постоянной проблемой:

  1. Первый запрос после запуска приложения занимает 13-15 секунд. Эту проблему я смог решить с помощью запроса на разминку, но я открыт для подходящих способов разминки.
  2. Последующие запросы выполняются намного быстрее.
  3. Если есть период неактивности (например, 1-2 минуты), следующий запрос снова занимает 13-15 секунд.

У меня есть подробные журналы, которые показывают, что соединение закрывается после бездействия:

DEBUG reactor.netty.http.client.HttpClient - [....] READ COMPLETE
DEBUG reactor.netty.http.client.HttpClient - [....] USER_EVENT: SslCloseCompletionEvent
DEBUG reactor.netty.http.client.HttpClient - [....] INACTIVE
DEBUG r.n.r.DefaultPooledConnectionProvider - [1a115ad9, L:/ip_address ! test.mysite.net/ip_of_target:443] onStateChange(PooledConnection{channel=[id: 1a115ad9, L:/ip_address ! R
.mysite.net/target_ip:443}}, [disconnecting])
DEBUG reactor.netty.http.client.HttpClient - [....] UNREGISTERED
@Configuration
public class WebClientConfig {

    @Bean
    public ConnectionProvider connectionProvider() {
        return ConnectionProvider.builder("MyApplicationConnection")
            .maxConnections(100) 
            .pendingAcquireTimeout(Duration.ofSeconds(60)) 
            .maxIdleTime(Duration.ofMinutes(30)) 
            .maxLifeTime(Duration.ofMinutes(60)) 
            .evictInBackground(Duration.ofMinutes(5)) 
            .build();
    }

    @Bean
    public HttpClient httpClient(ConnectionProvider connectionProvider) {
        return HttpClient.create(connectionProvider)
            .doOnConnected(connection ->
                connection.addHandlerLast(new ReadTimeoutHandler(10)) 
                          .addHandlerLast(new WriteTimeoutHandler(10))) 
            .wiretap("reactor.netty.http.client.HttpClient", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL); 
    }

    @Bean
    public WebClient webClient(HttpClient httpClient) {
        return WebClient.builder()
            .clientConnector(new ReactorClientHttpConnector(httpClient))
            .baseUrl("https://test.mysite.net")
            .defaultHeader(HttpHeaders.CONNECTION, "keep-alive") 
            .build();
    }
}

Я пробовал увеличить maxIdleTime и maxLifeTime, но это не дало никакого эффекта. Я хочу, чтобы мои последующие запросы выполнялись быстрее, даже если есть период бездействия. По сути, мое приложение представляет собой приложение на основе API, которое будет вызывать другие API с помощью веб-клиента. Если в течение некоторого времени к моему API не поступают запросы, это не должно замедлить следующий запрос.

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема была решена после включения кэширования DNS. Да, неактивные соединения освобождаются, но проблема была связана с дополнительными поисками DNS при каждом новом соединении.

return HttpClient.create(connectionProvider)
        .resolver(DefaultAddressResolverGroup.INSTANCE)

Другие вопросы по теме