程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

Spring WebClient(spring webclient 并发请求限制队列大小)

balukai 2025-07-27 18:37:32 文章精选 3 ℃

WebClient 是 Spring WebFlux 提供的一个非阻塞、响应式的 HTTP 客户端,用于替代传统的同步阻塞式客户端 RestTemplate。它是构建现代响应式微服务调用链的重要工具,适用于需要高性能、异步请求处理的场景。

一、什么是 WebClient?

  • 非阻塞 I/O:基于 Reactor 的 Mono 和 Flux,支持异步请求。
  • 函数式编程风格:使用链式调用方式编写清晰易读的代码。
  • 支持多种数据格式:JSON、XML、表单、流等。
  • 可扩展性强:支持拦截器、编码解码器、自定义过滤器等。
  • 与 Spring 生态集成良好:Spring Boot、Spring Security、R2DBC 等。

二、基本使用示例

1. 创建 WebClient 实例

WebClient webClient = WebClient.create("https://api.example.com");

也可以使用 builder 模式创建更复杂的配置:

WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.build();

2. GET 请求获取资源

Mono<User> userMono = webClient.get()
.uri("/users/{id}", 1)
.retrieve()
.bodyToMono(User.class);
userMono.subscribe(user -> System.out.println("User: " + user.getName()));

3. POST 请求提交数据

User newUser = new User("John", 30);
Mono<User> response = webClient.post()
.uri("/users")
.bodyValue(newUser)
.retrieve()
.bodyToMono(User.class);
response.subscribe(user -> System.out.println("Created user ID: " + user.getId()));

4. 处理错误(异常处理)

可以通过 .onStatus() 来捕获特定状态码的错误,并进行处理:

webClient.get()
.uri("/users/999")
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> {
return Mono.error(new RuntimeException("Client error"));
})
.onStatus(HttpStatus::is5xxServerError, clientResponse -> {
return Mono.error(new RuntimeException("Server error"));
})
.bodyToMono(User.class)
.subscribe(
user -> System.out.println("User: " + user.getName()),
err -> System.err.println("Error occurred: " + err.getMessage())
);

5. 获取 Flux 流式数据

如果接口返回的是多个对象(如数组或集合),可以使用 Flux<T> 接收:

Flux<User> usersFlux = webClient.get()
.uri("/users")
.retrieve()
.bodyToFlux(User.class);
usersFlux.subscribe(user -> System.out.println("User: " + user.getName()));

三、高级功能

1. 设置超时时间

可以通过配置底层的 ReactorResourceFactory 或直接使用 Netty 配置:

HttpClient httpClient = HttpClient.create()
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 5000)
.doOnConnected(conn -> conn
.addHandlerLast(new ReadTimeoutHandler(5))
.addHandlerLast(new WriteTimeoutHandler(5)));
WebClient webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();

2. 添加过滤器(拦截器)

WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.filter((request, next) -> {
ClientRequest newRequest = ClientRequest.from(request)
.header("X-API-Key", "your-secret-key")
.build();
return next.exchange(newRequest);
})
.build();

3. 使用 ExchangeFunction 自定义逻辑

ExchangeFunction 可以完全控制请求和响应过程:

ExchangeFunction exchangeFunction = (request, clientResponse) -> {
// 自定义逻辑
return ExchangeFunctions.createDefault().exchange(request, clientResponse);
};
WebClient webClient = WebClient.builder()
.exchangeFunction(exchangeFunction)
.build();

四、WebClient vs RestTemplate

特性

RestTemplate

WebClient

是否非阻塞

否(同步)

是(异步)

响应式编程支持

不支持

支持(Mono/Flux)

函数式风格

性能

一般

更高(适合高并发)

是否推荐新项目使用

已废弃

推荐

五、最佳实践建议

  1. 避免阻塞操作:不要在 WebClient 调用后立即调用 .block(),除非你确实需要等待结果。
  2. 合理设置超时:网络调用要设置合理的连接和读写超时时间。
  3. 统一异常处理:使用 .onStatus() 统一处理错误响应。
  4. 复用 WebClient 实例:一个应用中通常只需要一个或少数几个 WebClient 实例。
  5. 结合重试机制:可以配合 Resilience4j、Retryable、Spring Retry 等实现自动重试。

六、常见问题

Q:什么时候应该使用 WebClient?

  • 在 Spring WebFlux 项目中
  • 需要异步非阻塞调用
  • 需要处理大量并发请求
  • 需要流式数据处理(如 SSE)
  • 微服务间通信(尤其是网关层)

Q:WebClient 如何调试?

可以在请求中添加日志打印:

.filter((req, next) -> {
System.out.println("Request: " + req.method() + " " + req.url());
return next.exchange(req);
})

总结:

WebClient 是 Spring WebFlux 中用于发起非阻塞、响应式 HTTP 请求的核心组件,是现代 Spring 应用中进行服务调用的最佳选择。

Tags:

最近发表
标签列表