MST
星途 面试题库

面试题:Node.js网络通信重试机制的策略设计

假设你正在开发一个基于Node.js的应用,需要与一个不稳定的API进行网络通信,经常会遇到请求失败的情况。请设计一套重试机制的策略,包括但不限于重试次数、重试间隔时间的计算方式,并说明如何与超时机制协同工作,确保应用在面对网络问题时的稳定性和高效性。要求结合代码示例阐述。
31.0万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

重试机制策略设计

  1. 重试次数: 可以根据实际情况设定一个合理的重试次数,比如3次。如果多次重试都失败,可能说明问题较为严重,不适合继续重试。

  2. 重试间隔时间计算方式

    • 固定间隔:每次重试间隔固定时间,例如每次间隔1秒。这种方式简单直接,但在面对一些瞬时网络问题时可能不够灵活。
    • 指数退避:每次重试间隔时间呈指数增长,例如初始间隔为1秒,下次间隔为2秒,再下次为4秒等。这种方式可以避免短时间内频繁重试对服务器造成过大压力,尤其适用于服务器过载导致请求失败的情况。
  3. 与超时机制协同工作

    • 为每个请求设置一个总的超时时间,比如5秒。在重试过程中,如果累计重试时间加上当前请求时间超过总超时时间,则停止重试并返回失败。

代码示例(使用指数退避和超时机制)

const axios = require('axios');

async function makeRequestWithRetry(url, maxRetries = 3, baseRetryTime = 1000, totalTimeout = 5000) {
    let retries = 0;
    let elapsedTime = 0;
    while (retries < maxRetries) {
        try {
            const response = await Promise.race([
                axios.get(url),
                new Promise((_, reject) => {
                    setTimeout(() => {
                        reject(new Error('Request timed out'));
                    }, totalTimeout - elapsedTime);
                })
            ]);
            return response;
        } catch (error) {
            if (error.message.includes('Request timed out')) {
                throw error;
            }
            const retryTime = baseRetryTime * Math.pow(2, retries);
            elapsedTime += retryTime;
            if (elapsedTime > totalTimeout) {
                throw new Error('Total time for retries exceeded');
            }
            console.log(`Retry ${retries + 1} in ${retryTime / 1000} seconds...`);
            await new Promise(resolve => setTimeout(resolve, retryTime));
            retries++;
        }
    }
    throw new Error('Max retries reached, request failed');
}

// 使用示例
makeRequestWithRetry('https://unstable-api.example.com/api/data')
  .then(response => {
        console.log('Success:', response.data);
    })
  .catch(error => {
        console.error('Error:', error.message);
    });

在上述代码中:

  • makeRequestWithRetry 函数接受URL、最大重试次数 maxRetries、基础重试时间 baseRetryTime(单位毫秒)和总超时时间 totalTimeout(单位毫秒)作为参数。
  • 使用 Promise.race 来实现请求和超时的竞争,确保请求不会超过总超时时间。
  • 在每次请求失败时,计算下一次重试的间隔时间(指数退避),并累计已花费的时间。如果累计时间超过总超时时间,则停止重试并抛出错误。
  • 如果重试次数达到 maxRetries 仍未成功,也抛出错误。