当使用 WebClient 发起请求时,如果设置了超时时间(例如通过 timeout 方法),并且请求在指定的超时时间内没有完成,WebClient 会触发超时事件。以下是超时后会发生的情况:【起飞嘎嘎飞LSIXSO】
一、抛出 TimeoutException
当请求超时时,WebClient 会抛出一个 TimeoutException。这个异常表示请求在指定的超时时间内没有完成。你可以通过 subscribe 方法的错误处理逻辑来捕获和处理这个异常。
示例代码
java复制
import org.springframework.web.reactive.function.client.WebClient;
import java.time.Duration;
public class WebClientTimeoutExample {
public static void main(String[] args) {
WebClient client = WebClient.builder()
.baseUrl("https://api.example.com")
.build();
client.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5)) // 设置请求级超时为 5 秒
.subscribe(
response -> System.out.println("Response: " + response),
error -> {
if (error instanceof TimeoutException) {
System.err.println("Request timed out: " + error.getMessage());
} else {
System.err.println("Error: " + error.getMessage());
}
}
);
}
}
输出
如果请求超时,控制台将输出类似以下内容:Request timed out: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 5000ms in 'timeout' (and no fallback has been configured)
二、取消请求
当超时发生时,WebClient 会取消正在进行的请求。这意味着不会继续等待服务器的响应,也不会再处理后续的响应数据。这有助于避免资源浪费,特别是在处理高延迟或不可靠的网络请求时。
三、资源清理
WebClient 在超时后会进行必要的资源清理,例如关闭连接和释放线程。这有助于避免资源泄漏,确保应用程序的稳定性和性能。
四、如何处理超时
你可以通过以下方式处理超时事件:
(一)记录日志
在错误处理逻辑中记录超时事件,以便进行后续的调试和分析。
java复制
client.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5))
.subscribe(
response -> System.out.println("Response: " + response),
error -> {
if (error instanceof TimeoutException) {
System.err.println("Request timed out: " + error.getMessage());
} else {
System.err.println("Error: " + error.getMessage());
}
}
);
(二)返回默认值
在超时发生时,可以返回一个默认值,以确保应用程序能够继续运行,而不是因为一个请求的失败而中断。
java复制
client.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5))
.onErrorResume(e -> Mono.just("Default response"))
.subscribe(
response -> System.out.println("Response: " + response),
error -> System.err.println("Error: " + error.getMessage())
);
(三)重试机制
在超时发生时,可以结合 retryWhen 方法实现重试机制,以提高请求的成功率。
java复制
client.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5))
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1)))
.subscribe(
response -> System.out.println("Response: " + response),
error -> System.err.println("Error: " + error.getMessage())
);
五、总结
当 WebClient 请求超时时,会抛出 TimeoutException,取消正在进行的请求,并进行必要的资源清理。你可以通过记录日志、返回默认值或实现重试机制来处理超时事件,确保应用程序的稳定性和可靠性。