From 2055a60bcbbb13fa4fafc23b7a8205eab1775f34 Mon Sep 17 00:00:00 2001 From: song Date: Fri, 16 Jan 2026 18:51:07 +0800 Subject: [PATCH] =?UTF-8?q?fix(antigravity):=20429=20=E9=87=8D=E8=AF=953?= =?UTF-8?q?=E6=AC=A1=E5=90=8E=E9=99=90=E6=B5=81=E8=B4=A6=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 收到429后重试最多3次(指数退避) - 3次都失败后调用 handleUpstreamError 限流账户 - 移除无效的 URL fallback 逻辑(当前只有一个URL) --- .../service/antigravity_gateway_service.go | 48 +++++++++++++++---- 1 file changed, 38 insertions(+), 10 deletions(-) diff --git a/backend/internal/service/antigravity_gateway_service.go b/backend/internal/service/antigravity_gateway_service.go index 716fa3c4..347877ee 100644 --- a/backend/internal/service/antigravity_gateway_service.go +++ b/backend/internal/service/antigravity_gateway_service.go @@ -587,13 +587,27 @@ urlFallbackLoop: return nil, s.writeClaudeError(c, http.StatusBadGateway, "upstream_error", "Upstream request failed after retries") } - // 检查是否应触发 URL 降级(仅 429) - if resp.StatusCode == http.StatusTooManyRequests && urlIdx < len(availableURLs)-1 { + // 429 重试3次后限流账户 + if resp.StatusCode == http.StatusTooManyRequests { respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 2<<20)) _ = resp.Body.Close() - antigravity.DefaultURLAvailability.MarkUnavailable(baseURL) - log.Printf("%s URL fallback (HTTP 429): %s -> %s body=%s", prefix, baseURL, availableURLs[urlIdx+1], truncateForLog(respBody, 200)) - continue urlFallbackLoop + + if attempt < 3 { + log.Printf("%s status=429 retry=%d/3 body=%s", prefix, attempt, truncateForLog(respBody, 200)) + if !sleepAntigravityBackoffWithContext(ctx, attempt) { + return nil, ctx.Err() + } + continue + } + // 3次重试都失败,限流账户 + s.handleUpstreamError(ctx, prefix, account, resp.StatusCode, resp.Header, respBody, quotaScope) + log.Printf("%s status=429 rate_limited body=%s", prefix, truncateForLog(respBody, 200)) + resp = &http.Response{ + StatusCode: resp.StatusCode, + Header: resp.Header.Clone(), + Body: io.NopCloser(bytes.NewReader(respBody)), + } + break urlFallbackLoop } if resp.StatusCode >= 400 && s.shouldRetryUpstreamError(resp.StatusCode) { @@ -1131,13 +1145,27 @@ urlFallbackLoop: return nil, s.writeGoogleError(c, http.StatusBadGateway, "Upstream request failed after retries") } - // 检查是否应触发 URL 降级(仅 429) - if resp.StatusCode == http.StatusTooManyRequests && urlIdx < len(availableURLs)-1 { + // 429 重试3次后限流账户 + if resp.StatusCode == http.StatusTooManyRequests { respBody, _ := io.ReadAll(io.LimitReader(resp.Body, 2<<20)) _ = resp.Body.Close() - antigravity.DefaultURLAvailability.MarkUnavailable(baseURL) - log.Printf("%s URL fallback (HTTP 429): %s -> %s body=%s", prefix, baseURL, availableURLs[urlIdx+1], truncateForLog(respBody, 200)) - continue urlFallbackLoop + + if attempt < 3 { + log.Printf("%s status=429 retry=%d/3 body=%s", prefix, attempt, truncateForLog(respBody, 200)) + if !sleepAntigravityBackoffWithContext(ctx, attempt) { + return nil, ctx.Err() + } + continue + } + // 3次重试都失败,限流账户 + s.handleUpstreamError(ctx, prefix, account, resp.StatusCode, resp.Header, respBody, quotaScope) + log.Printf("%s status=429 rate_limited body=%s", prefix, truncateForLog(respBody, 200)) + resp = &http.Response{ + StatusCode: resp.StatusCode, + Header: resp.Header.Clone(), + Body: io.NopCloser(bytes.NewReader(respBody)), + } + break urlFallbackLoop } if resp.StatusCode >= 400 && s.shouldRetryUpstreamError(resp.StatusCode) {