當(dāng)使用 WebClient 發(fā)起請(qǐng)求時(shí),如果設(shè)置了超時(shí)時(shí)間(例如通過 timeout 方法),并且請(qǐng)求在指定的超時(shí)時(shí)間內(nèi)沒有完成,WebClient 會(huì)觸發(fā)超時(shí)事件。以下是超時(shí)后會(huì)發(fā)生的情況:【起飛嘎嘎飛LSIXSO】
一、拋出 TimeoutException
當(dāng)請(qǐng)求超時(shí)時(shí),WebClient 會(huì)拋出一個(gè) TimeoutException。這個(gè)異常表示請(qǐng)求在指定的超時(shí)時(shí)間內(nèi)沒有完成。你可以通過 subscribe 方法的錯(cuò)誤處理邏輯來捕獲和處理這個(gè)異常。
示例代碼
java復(fù)制
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)) // 設(shè)置請(qǐng)求級(jí)超時(shí)為 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());
}
}
);
}
}
輸出
如果請(qǐng)求超時(shí),控制臺(tái)將輸出類似以下內(nèi)容: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)
二、取消請(qǐng)求
當(dāng)超時(shí)發(fā)生時(shí),WebClient 會(huì)取消正在進(jìn)行的請(qǐng)求。這意味著不會(huì)繼續(xù)等待服務(wù)器的響應(yīng),也不會(huì)再處理后續(xù)的響應(yīng)數(shù)據(jù)。這有助于避免資源浪費(fèi),特別是在處理高延遲或不可靠的網(wǎng)絡(luò)請(qǐng)求時(shí)。
三、資源清理
WebClient 在超時(shí)后會(huì)進(jìn)行必要的資源清理,例如關(guān)閉連接和釋放線程。這有助于避免資源泄漏,確保應(yīng)用程序的穩(wěn)定性和性能。
四、如何處理超時(shí)
你可以通過以下方式處理超時(shí)事件:
(一)記錄日志
在錯(cuò)誤處理邏輯中記錄超時(shí)事件,以便進(jìn)行后續(xù)的調(diào)試和分析。
java復(fù)制
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());
}
}
);
(二)返回默認(rèn)值
在超時(shí)發(fā)生時(shí),可以返回一個(gè)默認(rèn)值,以確保應(yīng)用程序能夠繼續(xù)運(yùn)行,而不是因?yàn)橐粋€(gè)請(qǐng)求的失敗而中斷。
java復(fù)制
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())
);
(三)重試機(jī)制
在超時(shí)發(fā)生時(shí),可以結(jié)合 retryWhen 方法實(shí)現(xiàn)重試機(jī)制,以提高請(qǐng)求的成功率。
java復(fù)制
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())
);
五、總結(jié)
當(dāng) WebClient 請(qǐng)求超時(shí)時(shí),會(huì)拋出 TimeoutException,取消正在進(jìn)行的請(qǐng)求,并進(jìn)行必要的資源清理。你可以通過記錄日志、返回默認(rèn)值或?qū)崿F(xiàn)重試機(jī)制來處理超時(shí)事件,確保應(yīng)用程序的穩(wěn)定性和可靠性。