Merge pull request #899 from wanxunyang/feature/add-quota-check-decorator
Feature/add quota check decorator
This commit is contained in:
@@ -248,6 +248,35 @@ class RateLimiterService:
|
||||
def __init__(self):
|
||||
self.redis = aio_redis
|
||||
|
||||
async def check_tenant_rate_limit(self, tenant_id: uuid.UUID, limit: int) -> Tuple[bool, dict]:
|
||||
"""
|
||||
按 tenant_id 做 1 秒滑动窗口限速,限制值来自套餐配额 api_ops_rate_limit
|
||||
"""
|
||||
now = time.time()
|
||||
window_start = now - 1 # 1 秒窗口
|
||||
key = f"rate_limit:tenant_qps:{tenant_id}"
|
||||
|
||||
async with self.redis.pipeline() as pipe:
|
||||
# 清理 1 秒前的旧记录
|
||||
pipe.zremrangebyscore(key, 0, window_start)
|
||||
# 加入当前请求(score=时间戳,member=时间戳+随机数保证唯一)
|
||||
pipe.zadd(key, {f"{now}:{uuid.uuid4().hex}": now})
|
||||
# 统计窗口内请求数
|
||||
pipe.zcard(key)
|
||||
# 设置 key 过期(2 秒后自动清理)
|
||||
pipe.expire(key, 2)
|
||||
results = await pipe.execute()
|
||||
|
||||
current = results[2]
|
||||
remaining = max(0, limit - current)
|
||||
reset_time = int(now) + 1
|
||||
|
||||
return current <= limit, {
|
||||
"limit": limit,
|
||||
"remaining": remaining,
|
||||
"reset": reset_time,
|
||||
}
|
||||
|
||||
async def check_qps(self, api_key_id: uuid.UUID, limit: int) -> Tuple[bool, dict]:
|
||||
"""
|
||||
检查QPS限制
|
||||
|
||||
@@ -729,10 +729,21 @@ class ModelApiKeyService:
|
||||
@staticmethod
|
||||
def delete_api_key(db: Session, api_key_id: uuid.UUID) -> bool:
|
||||
"""删除API Key"""
|
||||
if not ModelApiKeyRepository.get_by_id(db, api_key_id):
|
||||
api_key = ModelApiKeyRepository.get_by_id(db, api_key_id)
|
||||
if not api_key:
|
||||
raise BusinessException("API Key不存在", BizCode.NOT_FOUND)
|
||||
|
||||
model_config_ids = [mc.id for mc in api_key.model_configs]
|
||||
|
||||
success = ModelApiKeyRepository.delete(db, api_key_id)
|
||||
|
||||
for model_config_id in model_config_ids:
|
||||
model_config = ModelConfigRepository.get_by_id(db, model_config_id)
|
||||
if model_config:
|
||||
has_active_key = any(key.is_active for key in model_config.api_keys)
|
||||
if not has_active_key and model_config.is_active:
|
||||
model_config.is_active = False
|
||||
|
||||
db.commit()
|
||||
return success
|
||||
|
||||
|
||||
Reference in New Issue
Block a user