From 43a30b5a1fe95b20f3c29a06bda2d1e89b7e1a04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B0=A2=E4=BF=8A=E7=94=B7?= Date: Thu, 18 Dec 2025 16:56:34 +0800 Subject: [PATCH] feat(apikey system): api key authentication qps optimization --- api/app/core/api_key_auth.py | 47 +++++++++++++++-------------- api/app/services/api_key_service.py | 2 +- 2 files changed, 25 insertions(+), 24 deletions(-) diff --git a/api/app/core/api_key_auth.py b/api/app/core/api_key_auth.py index a5db49a7..d90bb00d 100644 --- a/api/app/core/api_key_auth.py +++ b/api/app/core/api_key_auth.py @@ -70,29 +70,6 @@ def require_api_key( }) raise BusinessException("API Key 无效或已过期", BizCode.API_KEY_INVALID) - rate_limiter = RateLimiterService() - is_allowed, error_msg, rate_headers = await rate_limiter.check_all_limits(api_key_obj) - if not is_allowed: - logger.warning("API Key 限流触发", extra={ - "api_key_id": str(api_key_obj.id), - "endpoint": str(request.url), - "method": request.method, - "error_msg": error_msg - }) - # 根据错误消息判断限流类型 - if "QPS" in error_msg: - code = BizCode.API_KEY_QPS_LIMIT_EXCEEDED - elif "Daily" in error_msg: - code = BizCode.API_KEY_DAILY_LIMIT_EXCEEDED - else: - code = BizCode.API_KEY_QUOTA_EXCEEDED - - raise RateLimitException( - error_msg, - code, - rate_headers=rate_headers - ) - if scopes: missing_scopes = [] for scope in scopes: @@ -138,6 +115,30 @@ def require_api_key( scopes=api_key_obj.scopes, resource_id=api_key_obj.resource_id, ) + + rate_limiter = RateLimiterService() + is_allowed, error_msg, rate_headers = await rate_limiter.check_all_limits(api_key_obj) + if not is_allowed: + logger.warning("API Key 限流触发", extra={ + "api_key_id": str(api_key_obj.id), + "endpoint": str(request.url), + "method": request.method, + "error_msg": error_msg + }) + # 根据错误消息判断限流类型 + if "QPS" in error_msg: + code = BizCode.API_KEY_QPS_LIMIT_EXCEEDED + elif "Daily" in error_msg: + code = BizCode.API_KEY_DAILY_LIMIT_EXCEEDED + else: + code = BizCode.API_KEY_QUOTA_EXCEEDED + + raise RateLimitException( + error_msg, + code, + rate_headers=rate_headers + ) + start_time = time.perf_counter() response = await func(*args, **kwargs) end_time = time.perf_counter() diff --git a/api/app/services/api_key_service.py b/api/app/services/api_key_service.py index 2d7393e3..32cd578b 100644 --- a/api/app/services/api_key_service.py +++ b/api/app/services/api_key_service.py @@ -257,7 +257,7 @@ class RateLimiterService: key = f"rate_limit:qps:{api_key_id}" async with self.redis.pipeline() as pipe: pipe.incr(key) - pipe.expire(key, 1) # 1 秒过期 + pipe.expire(key, 1, nx=True) # 1 秒过期 results = await pipe.execute() current = results[0]