Правильный способ использования Spring WebClient в многопоточной среде
у меня есть один вопрос относительно Весна WebClient
в моем приложении мне нужно сделать много подобных вызовов API, иногда мне нужно изменить заголовки в вызовах (токен аутентификации). Поэтому возникает вопрос, что было бы лучше из двух вариантов:
-
чтобы создать один WebClient для всех входящих запросов к MyService.класс, сделав это
private final
поле, как код ниже:private final WebClient webClient = WebClient.builder() .baseUrl("https://another_host.com/api/get_inf") .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE) .defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE) .build();
здесь возникает другой вопрос: Является ли WebClient потокобезопасным? (потому что сервис используется многими нитями)
- для создания нового WebClient для каждого нового запроса, входящего в класс обслуживания.
Я хочу обеспечить максимальную производительность и использовать его правильно, но я не знаю, как WebClient работает внутри него, и как он ожидает быть использован.
спасибо вы.
1 ответов
две ключевые вещи о WebClient
:
- его HTTP-ресурсы (соединения, кэши и т. д.) управляются базовой библиотекой, на которую ссылается
ClientHttpConnector
что вы можете настроить наWebClient
-
WebClient
- это непреложный
имея это в виду, вы должны попытаться повторно использовать то же самое ClientHttpConnector
в вашем приложении, потому что это будет общий пул соединений - это, возможно, самое важное для производительности. Это средство вы должны попытаться вывести all WebClient
экземпляры из того же WebClient.create()
звонок. Spring Boot поможет вам в этом, создав и настроив для вас WebClient.Builder
bean, который вы можете ввести в любом месте вашего приложения.
, потому что WebClient
неизменяемо это потокобезопасно. WebClient
предназначен для использования в реактивной среде, где ничего не привязано к определенному потоку (это не означает, что вы не можете использовать в традиционном приложении сервлета).
если вы хотите изменить способ запросы сделаны, есть несколько способов добиться этого:
настройка вещей на этапе builder
WebClient baseClient = WebClient.create().baseUrl("https://example.org");
настройка вещей на основе каждого запроса
Mono<ClientResponse> response = baseClient.get().uri("/resource")
.header("token", "secret").exchange();
создать новый экземпляр клиента из существующего
// mutate() will *copy* the builder state and create a new one out of it
WebClient authClient = baseClient.mutate()
.defaultHeaders(headers -> {headers.add("token", "secret");})
.build();