From be814c5a56f91857759c1228e75706c78c1ff984 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Sun, 18 Jan 2026 00:04:22 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E5=87=AD=E8=AF=81?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E5=92=8C=E9=87=8D=E8=AF=95=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=E4=BB=A5=E9=81=BF=E5=85=8D=E5=B9=B6=E5=8F=91=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 移除 Gemini 服务中不必要的过期检查逻辑 - 在凭证刷新时添加随机延迟和最大重试次数限制 - 在流式和非流式请求重试时添加随机延迟 --- src/providers/gemini/gemini-core.js | 2 +- src/providers/provider-pool-manager.js | 16 ++++++++++++++-- src/utils/common.js | 10 ++++++++-- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/providers/gemini/gemini-core.js b/src/providers/gemini/gemini-core.js index 98aacc7..2359249 100644 --- a/src/providers/gemini/gemini-core.js +++ b/src/providers/gemini/gemini-core.js @@ -285,7 +285,7 @@ export class GeminiApiService { async initializeAuth(forceRefresh = false) { // 检查是否需要刷新 Token - const needsRefresh = forceRefresh || this.isExpiryDateNear(); + const needsRefresh = forceRefresh if (this.authClient.credentials.access_token && !needsRefresh) { // Token 有效且不需要刷新 diff --git a/src/providers/provider-pool-manager.js b/src/providers/provider-pool-manager.js index 0807f74..219b3e9 100644 --- a/src/providers/provider-pool-manager.js +++ b/src/providers/provider-pool-manager.js @@ -252,10 +252,22 @@ export class ProviderPoolManager { */ async _refreshNodeToken(providerType, providerStatus, force = false) { const config = providerStatus.config; - this._log('info', `Starting token refresh for node ${providerStatus.uuid} (${providerType})`); + + // 检查刷新次数是否已达上限(最大3次) + const currentRefreshCount = config.refreshCount || 0; + if (currentRefreshCount >= 3 && !force) { + this._log('warn', `Node ${providerStatus.uuid} has reached maximum refresh count (3), skipping refresh`); + return; + } + + // 添加5秒内的随机等待时间,避免并发刷新时的冲突 + const randomDelay = Math.floor(Math.random() * 5000); + this._log('info', `Starting token refresh for node ${providerStatus.uuid} (${providerType}) with ${randomDelay}ms delay`); + await new Promise(resolve => setTimeout(resolve, randomDelay)); try { - config.refreshCount = (config.refreshCount || 0) + 1; + // 增加刷新计数 + config.refreshCount = currentRefreshCount + 1; // 使用适配器进行刷新 const tempConfig = { diff --git a/src/utils/common.js b/src/utils/common.js index 0388c4d..886b9a2 100644 --- a/src/utils/common.js +++ b/src/utils/common.js @@ -345,7 +345,10 @@ export async function handleStreamRequest(res, service, model, requestBody, from // 凭证已被标记为不健康后,尝试切换到新凭证重试 // 不再依赖状态码判断,只要凭证被标记不健康且可以重试,就尝试切换 if (credentialMarkedUnhealthy && currentRetry < maxRetries && providerPoolManager && CONFIG) { - console.log(`[Stream Retry] Credential marked unhealthy. Attempting retry ${currentRetry + 1}/${maxRetries} with different credential...`); + // 增加10秒内的随机等待时间,避免所有请求同时切换凭证 + const randomDelay = Math.floor(Math.random() * 10000); // 0-10000毫秒 + console.log(`[Stream Retry] Credential marked unhealthy. Waiting ${randomDelay}ms before retry ${currentRetry + 1}/${maxRetries} with different credential...`); + await new Promise(resolve => setTimeout(resolve, randomDelay)); try { // 动态导入以避免循环依赖 @@ -475,7 +478,10 @@ export async function handleUnaryRequest(res, service, model, requestBody, fromP // 凭证已被标记为不健康后,尝试切换到新凭证重试 // 不再依赖状态码判断,只要凭证被标记不健康且可以重试,就尝试切换 if (credentialMarkedUnhealthy && currentRetry < maxRetries && providerPoolManager && CONFIG) { - console.log(`[Unary Retry] Credential marked unhealthy. Attempting retry ${currentRetry + 1}/${maxRetries} with different credential...`); + // 增加10秒内的随机等待时间,避免所有请求同时切换凭证 + const randomDelay = Math.floor(Math.random() * 10000); // 0-10000毫秒 + console.log(`[Unary Retry] Credential marked unhealthy. Waiting ${randomDelay}ms before retry ${currentRetry + 1}/${maxRetries} with different credential...`); + await new Promise(resolve => setTimeout(resolve, randomDelay)); try { // 动态导入以避免循环依赖