Spring Boot WebClient OAuth - 同时命中多个请求时超时
Posted
技术标签:
【中文标题】Spring Boot WebClient OAuth - 同时命中多个请求时超时【英文标题】:Spring Boot WebClient OAuth - Got timeout when hit multiple request in same time 【发布时间】:2021-06-23 22:51:22 【问题描述】:我正在使用带有 webflux 和 oauth2-client 的 spring boot (2.4.4),我的代码是从 API 服务器成功获取的,当我使用邮递员点击时,每次点击的响应时间约为 500 毫秒。但是当我使用 jMeter 同时击中 10-100 个数据时,它会导致错误超时。我的代码是错误的还是我的代码中遗漏了什么?
这是我的 OAuth 配置:
@Bean
public ReactiveOAuth2AuthorizedClientManager authorizedClientManager(ReactiveClientRegistrationRepository clientRegistrationRepository, ReactiveOAuth2AuthorizedClientService authorizedClientService)
ReactiveOAuth2AuthorizedClientProvider authorizedClientProvider = ReactiveOAuth2AuthorizedClientProviderBuilder.builder().clientCredentials().authorizationCode().refreshToken().build();
AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager authorizedClientManager = new AuthorizedClientServiceReactiveOAuth2AuthorizedClientManager(clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider);
return authorizedClientManager;
@Bean
public WebClient webClient(ReactiveOAuth2AuthorizedClientManager authorizedClientManager)
ServerOAuth2AuthorizedClientExchangeFilterFunction oauth = new ServerOAuth2AuthorizedClientExchangeFilterFunction(authorizedClientManager);
oauth.setDefaultClientRegistrationId("custom-registrationId");
WebClient.Builder builder = WebClient.builder();
builder.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
builder.filter(oauth);
return builder.build();
我的 webclient 上的 impementation 使用 block,因为我需要在发送到客户端之前解析来自 API 的响应
@Autowired
private WebClient webClient;
String response = webClient.post()
.uri(URL_API)
.bodyValue(jsonRequest)
.exchangeToMono(clientResponse -> clientResponse.bodyToMono(String.class))
.timeout(Duration.ofMillis(10000))
.share().block();
问题出在我使用 jMeter 时。当我直接访问 API 服务器时,一切都成功了,但不是通过我的应用程序时
reactor.core.Exceptions$ReactiveException: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 10000ms in 'flatMap' (and no fallback has been configured)
【问题讨论】:
不要在non-blocking
框架中使用block
。使用flatMap
或map
。
嘿,谢谢。我不知道我可以使用它,因为这个反应式框架我不能阻止一切对吗?
【参考方案1】:
感谢Toerktumlare,我对如何编写代码有了启发。所以我认为在这个非阻塞框架中最好这样写而不是 block()
Mono<String> response = webClient.post()
.uri(URL_API)
.bodyValue(jsonRequest)
.exchangeToMono(clientResponse -> clientResponse.bodyToMono(String.class))
.timeout(Duration.ofMillis(10000));
Mono<Object> result = response.map(res ->
// Throw the logic parsing and other from response in here
)
return result;
【讨论】:
以上是关于Spring Boot WebClient OAuth - 同时命中多个请求时超时的主要内容,如果未能解决你的问题,请参考以下文章
使用 Spring Boot WebClient 时如何拦截请求
使用 Spring Boot 2 WebClient 从响应中获取标头
Spring boot 2 WebClient在订阅者中获取上下文参数