Правильный способ настройки тайм-аута чтения запроса на Spring 5 WebClient

Контекст

Я пытаюсь найти лучший способ объединить Spring 5 WebClient и Hystrix. Используя Hystrix, я устанавливаю разные тайм-ауты для разных типов запросов, выполняемых WebClient.

Когда Hystrix достигает тайм-аута, я также хочу убедиться, что WebClient закроет свое соединение. Раньше при использовании AsyncHttpClient это делалось путем установки requestTimeout перед выполнением конкретного вызова. Однако установка времени ожидания запроса на WebClient намного сложнее и должна выполняться на ClientHttpConnector в соответствии с этим ответом.

Брайан Козел отмечает, что оптимально использовать одни и те же ClientHttpConnector во всем приложении. Однако, поскольку тайм-аут запроса должен быть установлен на ClientHttpConnector, это не представляется возможным.

Вопрос

В Spring Reactive WebClient есть ли правильный способ установить время ожидания для запроса, но при этом использовать один ClientHttpConnector?


person Wyko    schedule 05.06.2018    source источник
comment
Не могли бы вы упростить свой вопрос? Кажется, это 3 вопроса в одном - пожалуйста, сосредоточьтесь на одном: 1) поддерживает ли spring cloud netflix webflux? 2) Какие существуют варианты тайм-аута в WebClient и чем они отличаются? 3) Есть ли способ установить время ожидания ответа для каждого запроса с помощью WebClient?   -  person Brian Clozel    schedule 05.06.2018
comment
Привет @BrianClozel, спасибо за быстрый ответ. Я попытался уточнить свой вопрос в редактировании. Мой вопрос 3), устанавливая тайм-аут ответа для каждого запроса, но при этом повторно используя тот же ClientHttpConnector, что вы предлагаете делать из соображений производительности.   -  person Wyko    schedule 05.06.2018


Ответы (1)


Операции тайм-аута, которые вы можете настроить на клиентском соединителе, имеют довольно низкий уровень: они касаются тайм-аутов сокета/соединения. Эту настройку нельзя выполнить на уровне запроса, так как соединения могут быть общими и повторно использоваться в пуле соединений.

Этот вопрос касается тайм-аутов ответа, поскольку вы, похоже, заботитесь о количестве времени для получения ответа для каждого запроса.

В этом случае вы можете использовать оператор timeout для каждого запроса:

Mono<UserData> result = this.webClient.get()
                .uri("/user")
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(UserData.class)
                .timeout(Duration.ofSeconds(10));

Оператор тайм-аута вызовет TimeoutException в конвейере; вы можете использовать один из операторов onError*, чтобы определить, что следует делать в таких случаях. В качестве альтернативы вы можете напрямую использовать вариант timeout(Duration, Mono), обеспечивающий запасной вариант.

person Brian Clozel    schedule 06.06.2018
comment
Hystrix также выдает какое-то исключение тайм-аута, но достижение этого тайм-аута не означает, что соединение HTTP-клиента будет немедленно закрыто, верно? Или это так? - person Nils Breunese; 08.06.2018
comment
Насколько я знаю, это относится к реактору-нетти. Но это зависит от базовой клиентской библиотеки, настроена ли она для пула соединений и т. д. - person Brian Clozel; 08.06.2018