當使用 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,取消正在進行的請求,并進行必要的資源清理。你可以通過記錄日志、返回默認值或實現重試機制來處理超時事件,確保應用程序的穩定性和可靠性。