diff --git a/app/router/gemini_routes.py b/app/router/gemini_routes.py index 189c300..8e9d6c6 100644 --- a/app/router/gemini_routes.py +++ b/app/router/gemini_routes.py @@ -50,7 +50,7 @@ async def list_models( logger.info("Handling Gemini models list request") try: - api_key = await key_manager.get_first_valid_key() + api_key = await key_manager.get_random_valid_key() if not api_key: raise HTTPException(status_code=503, detail="No valid API keys available to fetch models.") logger.info(f"Using API key: {redact_key_for_logging(api_key)}") diff --git a/app/router/openai_compatiable_routes.py b/app/router/openai_compatiable_routes.py index 92730d0..958c8ea 100644 --- a/app/router/openai_compatiable_routes.py +++ b/app/router/openai_compatiable_routes.py @@ -46,7 +46,7 @@ async def list_models( operation_name = "list_models" async with handle_route_errors(logger, operation_name): logger.info("Handling models list request") - api_key = await key_manager.get_first_valid_key() + api_key = await key_manager.get_random_valid_key() logger.info(f"Using API key: {redact_key_for_logging(api_key)}") return await openai_service.get_models(api_key) diff --git a/app/router/openai_routes.py b/app/router/openai_routes.py index e6cf9ae..2c590bb 100644 --- a/app/router/openai_routes.py +++ b/app/router/openai_routes.py @@ -60,7 +60,7 @@ async def list_models( operation_name = "list_models" async with handle_route_errors(logger, operation_name): logger.info("Handling models list request") - api_key = await key_manager.get_first_valid_key() + api_key = await key_manager.get_random_valid_key() logger.info(f"Using API key: {redact_key_for_logging(api_key)}") return await model_service.get_gemini_openai_models(api_key) diff --git a/app/router/vertex_express_routes.py b/app/router/vertex_express_routes.py index b4d57c8..1809300 100644 --- a/app/router/vertex_express_routes.py +++ b/app/router/vertex_express_routes.py @@ -46,7 +46,7 @@ async def list_models( logger.info("Handling Gemini models list request") try: - api_key = await key_manager.get_first_valid_key() + api_key = await key_manager.get_random_valid_key() if not api_key: raise HTTPException(status_code=503, detail="No valid API keys available to fetch models.") logger.info(f"Using API key: {redact_key_for_logging(api_key)}") diff --git a/app/service/config/config_service.py b/app/service/config/config_service.py index 10dfa21..64c91c8 100644 --- a/app/service/config/config_service.py +++ b/app/service/config/config_service.py @@ -230,7 +230,7 @@ class ConfigService: key_manager = await get_key_manager_instance() model_service = ModelService() - api_key = await key_manager.get_first_valid_key() + api_key = await key_manager.get_random_valid_key() if not api_key: logger.error("No valid API keys available to fetch model list for UI.") raise HTTPException( diff --git a/app/service/key/key_manager.py b/app/service/key/key_manager.py index efa0d11..d81b6b1 100644 --- a/app/service/key/key_manager.py +++ b/app/service/key/key_manager.py @@ -1,4 +1,5 @@ import asyncio +import random from itertools import cycle from typing import Dict, Union @@ -195,6 +196,25 @@ class KeyManager: return "" return self.api_keys[0] + async def get_random_valid_key(self) -> str: + """获取随机的有效API key""" + valid_keys = [] + async with self.failure_count_lock: + for key in self.key_failure_counts: + if self.key_failure_counts[key] < self.MAX_FAILURES: + valid_keys.append(key) + + if valid_keys: + return random.choice(valid_keys) + + # 如果没有有效的key,返回第一个key作为fallback + if self.api_keys: + logger.warning("No valid keys available, returning first key as fallback.") + return self.api_keys[0] + + logger.warning("API key list is empty, cannot get random valid key.") + return "" + _singleton_instance = None _singleton_lock = asyncio.Lock()