You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

异步请求站点JSON数据返回Error 429 有哪些可行的规避方案?

避免HTTP 429请求超限错误的实现方案

429错误本质是目标站点的限流机制触发,针对你当前异步批量请求的场景,可通过以下机制解决:

1. 全局请求速率管控

  • 采用令牌桶或漏桶算法统一限制所有异步请求的QPS和并发数,Kotlin协程场景可通过固定容量的信号量实现,同时设置两次请求的最小时间间隔,确保单位时间内的请求总量低于站点限流阈值。
  • 所有getJsonElementByUrl的调用必须先经过全局限流器校验,拿到执行许可后再发起请求,避免异步任务无节制并发。

2. 429错误适配与退避重试

  • 捕获429错误后禁止立即重试,实现指数退避策略:首次重试等待1s,第二次等待2s,第三次等待4s,最多设置3-5次重试上限,避免无效请求进一步加剧限流。
  • 优先读取响应头中的Retry-After字段,服务端通常会在该字段中明确标注可再次请求的等待时长,按该值执行等待比自定义退避策略兼容性更高。

3. 请求逻辑优化

你现有代码未做HTTP状态码校验,可先调整请求逻辑适配限流场景,参考优化代码:

private fun getJsonElementByUrl(url: String): JsonElement {
    val connection = URL(url).openConnection() as HttpURLConnection
    try {
        when (connection.responseCode) {
            429 -> {
                val retryAfter = connection.getHeaderField("Retry-After")?.toLongOrNull() ?: 1
                throw RuntimeException("429限流触发,需等待${retryAfter}秒后重试")
            }
            200 -> {
                BufferedReader(InputStreamReader(connection.inputStream)).use { reader ->
                    val sb = StringBuilder()
                    var inputLine: String?
                    while (reader.readLine().also { inputLine = it } != null) {
                        sb.append(inputLine)
                    }
                    return JsonParser().parse(sb.toString())
                }
            }
            else -> throw RuntimeException("请求失败,响应码:${connection.responseCode}")
        }
    } finally {
        connection.disconnect()
    }
}
  • 引入HTTP连接池复用TCP连接,既可以降低请求开销,也能更方便地统一管控所有请求流量。
  • 若目标站点支持批量接口,优先用一次批量请求代替多次单个数据请求,从根源上降低请求总量。

4. 辅助优化手段

  • 配置合规的User-Agent请求头,避免被服务端判定为恶意爬虫触发额外限流规则。
  • 如有多IP资源可配置IP轮询策略,分散单IP的请求压力,进一步降低限流概率。

内容的提问来源于stack exchange,提问作者Ta3ik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 15:45:04