数码工坊
白蓝主题五 · 清爽阅读
首页  > 数据备份

网络请求如何重试:让数据备份更可靠

数据备份时,网络请求失败是常有的事。比如你设置好了定时同步,结果公司网络突然卡了一下,上传中断,备份没成功。这时候,光靠手动重来一遍太麻烦,得让程序自己知道“失败了就再试几次”。

为什么需要重试机制

网络不稳定、服务器临时过载、DNS 解析超时,这些都可能导致一次请求失败。但很多情况下,几秒后重试就能成功。比如你在咖啡馆连 Wi-Fi 备份照片,信号波动导致上传中断,如果程序能自动重试,你就不用盯着进度条手动点“重试”了。

简单的重试逻辑怎么写

最基础的做法是用循环加延迟。比如发送一个 HTTP 请求,失败后等两秒再试,最多试三次。

function fetchDataWithRetry(url, retries = 3, delay = 2000) {
  return new Promise((resolve, reject) => {
    const attempt = (count) => {
      fetch(url)
        .then(resolve)
        .catch((err) => {
          if (count >= retries) {
            reject(err);
          } else {
            setTimeout(() => {
              console.log(`请求失败,${delay/1000}秒后重试,剩余次数: ${retries - count}`);
              attempt(count + 1);
            }, delay);
          }
        });
    };
    attempt(1);
  });
}

调用这个函数,就算第一次网络抖动,它也会自动再试两次。

别盲目重试

不是所有失败都值得重试。比如返回 404 是资源不存在,再试十次也没用;而 503 服务暂时不可用,重试就有意义。应该根据错误类型决定是否重试。

const shouldRetry = (error) => {
  if (error.status) {
    return [500, 502, 503, 504].includes(error.status);
  }
  // 网络断开、超时也重试
  return error.name === 'TypeError' || error.name === 'TimeoutError';
};

加入指数退避更聪明

连续重试间隔太短,可能让服务器雪上加霜。更好的方式是“越往后等越久”,比如第一次等 2 秒,第二次 4 秒,第三次 8 秒。

function exponentialBackoff(retryCount) {
  const delay = Math.pow(2, retryCount) * 1000; // 2^count 秒
  return delay;
}

结合前面的逻辑,每次重试的等待时间翻倍,既给了系统恢复时间,又避免了密集冲击。

实际应用场景

比如你写的备份脚本要往云存储上传文件,网络请求一旦失败,可以自动触发重试。配合日志记录,还能知道哪次传失败了、重试了几次才成功,方便排查问题。

有些现成的库也能帮你处理,比如 Axios 的拦截器加上重试插件,或者用 got、ky 这类支持原生重试的 HTTP 客户端,省得从零造轮子。

关键是在不稳定环境中保持任务的韧性。数据备份不是一锤子买卖,中间出点岔子,程序得能自己爬起来继续干。