面试题答案
一键面试重试次数设定策略
通常应根据业务需求和网络环境来设定合理的重试次数。如果请求资源相对稳定且网络环境良好,可以设置较少的重试次数(如3 - 5次);若请求的资源经常出现临时性问题或网络不稳定,可适当增加重试次数(如10次)。但不宜设置过大,避免无限重试占用过多资源。
重试间隔控制策略
- 固定间隔:每次重试间隔固定时长,简单直观,但可能在网络故障较复杂时效率不高。
- 指数退避:每次重试间隔时间以指数级增长,例如初始间隔1秒,下次2秒,再下次4秒等。这种方式能在避免频繁重试给服务器造成压力的同时,给予网络足够时间恢复。
- 随机化指数退避:在指数退避基础上,给每次重试间隔添加一定随机因子,避免多个请求同时重试导致的“惊群效应”。
处理不同类型网络错误策略
- 临时性错误:如超时、连接重置等,可进行重试。
- 永久性错误:如目标地址不存在、权限不足等,不应重试,直接返回错误给调用方。
代码示例
use std::time::Duration;
use reqwest::Error;
async fn send_request_with_retry(url: &str, max_retries: u32, initial_delay: Duration) -> Result<String, Error> {
let mut retry_count = 0;
let mut delay = initial_delay;
loop {
match reqwest::get(url).await {
Ok(response) => {
if response.status().is_success() {
return response.text().await;
} else {
eprintln!("Non - success status code: {}", response.status());
}
}
Err(e) => {
eprintln!("Request failed: {}", e);
if retry_count >= max_retries {
return Err(e);
}
}
}
std::thread::sleep(delay);
delay = delay.mul_f32(2.0) as Duration; // 指数退避
retry_count += 1;
}
}
调用示例:
#[tokio::main]
async fn main() {
let url = "https://example.com";
let max_retries = 3;
let initial_delay = Duration::from_secs(1);
match send_request_with_retry(url, max_retries, initial_delay).await {
Ok(response) => println!("Response: {}", response),
Err(e) => eprintln!("Final error: {}", e),
}
}