返回教程列表
教程2026年7月2日7 分钟阅读

接口调用失败后怎么做:重试、并发与成功率策略

了解 Just One API 实时采集接口失败后的处理方式:对瞬态故障进行有上限的退避重试,通过业务码判断、并发控制、日志和备用版本提升单位时间内的成功请求数。

先说结论

接口调用不是 100% 成功,这是实时数据采集类接口的正常现象。请求可能受到目标平台状态、网络波动、上游页面变化、单次采集链路和客户端超时设置影响。调用失败后,正确做法不是停止任务,而是根据业务码和错误类型,对可重试错误进行有上限的短暂退避重试。

Just One API 文档说明,API 没有通用的调用速率限制。也就是说,失败后不需要因为担心统一并发限制而把请求长时间排队。你可以根据业务需求调大或调小并发:想在更短时间内完成更多采集,就提高并发;想降低本地资源占用、让任务跑得更平缓,就降低并发。

需要注意的是,少数高并发接口如果在文档中标明了特定速率限制,应以对应接口文档为准。重试和并发是提升成功量的工具,但仍然应该有最大重试次数、超时、日志和停止条件。

先看 code,不要只看 HTTP 状态

Just One API 的业务结果要看返回体里的 code 字段。按 API 使用指南code0 表示成功,非成功业务码需要按类型处理。

  • 0 表示成功,可以进入业务处理。
  • 301 表示采集失败,请重试,适合短暂退避后重试。
  • 500 表示内部服务器错误,通常可以重试,但要有最大次数。
  • 302 表示超出速率限制,如果某个接口出现这个业务码,应降低该接口并发或增加等待。
  • 303 表示超出每日调用限额,应停止重试并等待额度周期重置;该情况可能同时返回 HTTP 429
  • 100400600601602 通常不是靠重复请求解决的问题,应该检查 Token、参数、权限、余额或 Token 限额。
  • HTTP 超时、连接中断、DNS 或网络错误一般也可以进入重试队列。
  • HTTP 层只建议重试网络错误、408429 和临时 5xx;其他 4xx 通常需要先修正请求或认证。

文档中的业务码表也标明,code: 0 的成功请求会计费,非成功业务码不计费。即便如此,也不要无限重试;无限重试会浪费任务时间,让日志变得不可读,也可能掩盖参数错误。

为什么要及时但有节制地重试

很多失败是短暂状态,不代表同一个参数下一次一定失败。实时采集链路里,单次请求可能遇到目标平台短时波动、代理链路抖动、页面结构临时异常或客户端等待时间不够。使用带随机抖动的指数退避,可以在同一个任务窗口内恢复一部分失败请求,又避免对已经承压的服务形成同步请求峰值。

对批量任务来说,目标不是让每一次尝试都成功,而是在同样时间内拿到更多成功结果。假设某个任务在当前时段单次成功率偏低,如果只串行慢慢请求,总成功量会很低;如果用更高并发持续推进,即使成功率没有明显提高,单位时间内的成功次数仍然可能很可观。

这是吞吐量思路,而不是单次成功率思路。你应该同时观察成功率和每分钟成功数。成功率低但并发高时,每分钟成功数可能仍然满足业务;成功率高但并发太低时,整体任务可能仍然跑得太慢。

推荐的重试策略

建议把失败处理写成明确的策略,而不是在业务代码里临时补几个 if

  • 301、网络错误、超时和临时 500 使用短暂的指数退避和随机抖动后重试。
  • 给每个请求设置最大尝试次数,例如 3 到 5 次,避免无限循环。
  • 每次重试都记录尝试次数、接口路径、版本、参数摘要、业务 code、耗时和错误信息。
  • 100303400600601602 这类额度、配置或账户问题直接停止,不要盲目重试。
  • 如果出现 302,说明该接口或当前账户可能触发了特定限制,应降低该接口并发或增加等待;服务器返回 Retry-After 时应优先遵循。
  • 对批量任务,可以把可重试的失败项放入延迟队列,让 worker 继续消费,而不是让整个任务停下来。

Just One API 文档建议请求超时时间设置为 120 秒;如果业务无法等待这么久,也建议至少设置 60 秒。超时时间太短会把本来可能成功的请求误判为失败,从而增加不必要的重试。

并发是业务旋钮

Just One API 没有通用调用速率限制,所以并发可以按你的业务目标调整。并发不是越大越好,也不是越小越稳,它应该服务于你的任务目标。

  • 需要尽快完成批量采集时,提高并发,让更多请求同时推进。
  • 本地机器、网络出口或下游数据库压力较大时,降低并发。
  • 某个接口短时间成功率下降时,可以提高并发保持成功吞吐,也可以降低并发减少资源浪费,取决于业务优先级。
  • 如果任务对实时性不敏感,可以用较低并发慢慢跑;如果任务有时间窗口,就应该按成功数目标反推并发。

一个简单估算:如果当前单次成功率约为 20%,每分钟发起 1000 次尝试,理论上每分钟约有 200 次成功;如果每分钟只发起 50 次尝试,理论上只有约 10 次成功。这只是吞吐量估算,不是成功率承诺,但它说明了为什么低成功率接口在大并发下仍然可能产生可观结果。

一个可落地的配置

可以先把并发、超时和重试次数做成配置,方便按接口和业务场景调整。

json
{
  "default": {
    "concurrency": 100,
    "timeoutMs": 120000,
    "maxAttempts": 4
  },
  "slowBatchJob": {
    "concurrency": 30,
    "timeoutMs": 120000,
    "maxAttempts": 5
  },
  "urgentBatchJob": {
    "concurrency": 300,
    "timeoutMs": 90000,
    "maxAttempts": 3
  }
}

这里的数字不是固定推荐值,而是配置形态示例。你应该根据自身机器、网络、接口表现、任务时效和下游写入能力调整。

伪代码示例

下面的示例展示了一个最小重试判断。真实项目里还应该加队列、日志、限时取消和结果去重。

js
const retryableCodes = new Set([301, 500]);
const stopCodes = new Set([100, 303, 400, 600, 601, 602]);
const sleep = (milliseconds) =>
  new Promise((resolve) => setTimeout(resolve, milliseconds));

function retryDelayMs(attempt, retryAfter) {
  const retryAfterValue = retryAfter?.trim();
  if (retryAfterValue) {
    const retryAfterSeconds = Number(retryAfterValue);
    if (Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0) {
      return retryAfterSeconds * 1000;
    }

    const retryAt = Date.parse(retryAfterValue);
    if (Number.isFinite(retryAt)) {
      return Math.max(0, retryAt - Date.now());
    }
  }

  return Math.min(500 * 2 ** (attempt - 1), 8_000) + Math.random() * 250;
}

async function callWithRetry(callApi, maxAttempts = 4) {
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
    let response;

    try {
      response = await callApi();
    } catch (error) {
      if (attempt === maxAttempts) {
        throw error;
      }

      await sleep(retryDelayMs(attempt));
      continue;
    }

    const result = await response.json().catch(() => null);

    if (result?.code === 303) {
      throw new Error("Daily quota exceeded; wait for the quota window to reset");
    }

    if (!response.ok) {
      const retryableHttp =
        response.status === 408 ||
        response.status === 429 ||
        response.status >= 500;

      if (!retryableHttp || attempt === maxAttempts) {
        throw new Error(`HTTP ${response.status}: request failed`);
      }

      await sleep(retryDelayMs(attempt, response.headers.get("retry-after")));
      continue;
    }

    if (!result) {
      throw new Error("API returned an invalid JSON response");
    }

    if (result.code === 0) {
      return result.data;
    }

    if (result.code === 302) {
      if (attempt === maxAttempts) {
        throw new Error("Rate limit persisted after all retry attempts");
      }

      await sleep(retryDelayMs(attempt, response.headers.get("retry-after")));
      continue;
    }

    if (stopCodes.has(result.code) || !retryableCodes.has(result.code)) {
      throw new Error(`Do not retry code ${result.code}: ${result.message}`);
    }

    if (attempt === maxAttempts) {
      throw new Error(`API failed with code ${result.code}: ${result.message}`);
    }

    await sleep(retryDelayMs(attempt));
  }
}

这个示例的重点是:成功立即返回,只对可重试错误进行有上限的指数退避,存在有效 Retry-After 时遵循服务端等待时间,不可重试错误尽早停止。示例假设 callApi 返回 Fetch 风格的 Response,并且只有传输层故障会抛出异常。生产环境还应把持续出现的 302429 信号反馈给接口并发控制。

失败重试时还要做去重

重试会带来一个工程问题:同一个业务对象可能被多次尝试,也可能在不同尝试中返回成功。为了避免重复写入,建议用业务唯一键做去重。

  • 笔记详情可以用平台、接口版本和笔记 ID 作为请求键。
  • 商品详情可以用平台和商品 ID 作为请求键。
  • 搜索任务可以用关键词、页码、排序方式和时间窗口作为请求键。
  • 入库时使用唯一索引或幂等写入,避免同一条数据重复保存。

重试策略越积极,去重和日志越重要。否则你会看到成功量上升,但下游数据变脏。

什么时候需要调整并发

并发不是写死之后就不动的配置。建议根据下面几个指标动态调整。

  • 每分钟成功数低于目标,可以提高并发或增加重试次数。
  • 本地 CPU、内存、网络或数据库写入压力过高,应降低并发。
  • 302 增多,应降低对应接口并发或增加等待。
  • 301 增多但成功数仍满足业务,可以维持当前策略并持续观察。
  • 超时增多,应先检查超时设置是否过短,再考虑降低并发或切换接口版本。

如果同一个接口有多个版本,也可以结合 接口版本号说明 中的思路,把其他版本作为备用链路。某个版本短时间压力较大或成功率下降时,切换到已测试过的版本,往往比无限重试同一个版本更有效。

常见问题

接口失败后要等一段时间再重试吗

建议为可重试错误增加短暂等待。对 301、网络错误、超时、408 和临时 5xx,使用带随机抖动且有上限的指数退避;遇到 302 或 HTTP 429 时,优先遵循 Retry-After 并降低接口并发;遇到 303 时,应等待每日额度周期重置。

成功率低是不是就不能用了

不是。成功率低说明单次尝试不稳定,但如果业务允许并发推进,单位时间成功数仍然可能很高。批量采集时应看每分钟成功数、失败成本和业务时效,而不是只看单次成功率。

并发是不是越高越好

不是。并发越高,单位时间尝试数越多,但本地资源、网络、下游数据库和日志系统压力也会升高。合理做法是以成功数目标为导向逐步调高,并持续观察错误码和资源占用。

所有错误都应该重试吗

不是。参数错误、Token 无效、权限不足、余额不足、Token 限额超限这类问题需要先修复配置或账户状态。直接重试不会解决问题。

下一步

接入前先阅读 API 使用指南,确认业务码、超时建议和认证方式。然后为你的采集任务设置并发、最大重试次数、超时时间和失败日志。准备调用时,登录 JustOneAPI Dashboard 获取 Token,并把真实 Token 保存在安全配置中。

继续使用 Just One API

登录 Dashboard 获取 Token,查看完整 API 文档,或打开 MCP GitHub 项目了解最新配置。