修复 单日绘图计数 添加原子性判断和增加
修复 高并发下会多次请求token的bug 现在都单次请求 使用 ConcurrentDictionary
This commit is contained in:
@@ -76,17 +76,6 @@ namespace LMS.service.Extensions.Attributes
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 检查日使用限制
|
||||
if (tokenConfig.DailyLimit > 0 && tokenConfig.DailyUsage >= tokenConfig.DailyLimit)
|
||||
{
|
||||
logger.LogWarning($"Token日限制已达上限: {_token}, 当前使用: {tokenConfig.DailyUsage}, 限制: {tokenConfig.DailyLimit}");
|
||||
context.Result = new ObjectResult("Daily limit exceeded")
|
||||
{
|
||||
StatusCode = StatusCodes.Status403Forbidden
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
// 6. 检查总使用限制
|
||||
if (tokenConfig.TotalLimit > 0 && tokenConfig.TotalUsage >= tokenConfig.TotalLimit)
|
||||
{
|
||||
@@ -98,24 +87,6 @@ namespace LMS.service.Extensions.Attributes
|
||||
return;
|
||||
}
|
||||
|
||||
// 7. 并发控制
|
||||
var (maxCount, currentlyExecuting, available) = usageTracker.GetConcurrencyStatus(_token);
|
||||
logger.LogInformation($"Token并发状态: {_token}, 最大: {maxCount}, 执行中: {currentlyExecuting}, 可用: {available}");
|
||||
|
||||
// 等待获取并发许可
|
||||
_concurrencyAcquired = await usageTracker.WaitForConcurrencyPermitAsync(_token);
|
||||
if (!_concurrencyAcquired)
|
||||
{
|
||||
logger.LogInformation($"Token并发限制超出: {_token}, 并发限制: {tokenConfig.ConcurrencyLimit}");
|
||||
context.Result = new ObjectResult($"Concurrency limit exceeded (max: {tokenConfig.ConcurrencyLimit})")
|
||||
{
|
||||
StatusCode = StatusCodes.Status429TooManyRequests
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation($"Token验证成功,开始处理请求: {_token}, 并发限制: {tokenConfig.ConcurrencyLimit}");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(tokenConfig.UseToken))
|
||||
{
|
||||
context.Result = new ObjectResult($"Token Error")
|
||||
@@ -125,18 +96,67 @@ namespace LMS.service.Extensions.Attributes
|
||||
return;
|
||||
}
|
||||
|
||||
// 7. 并发控制
|
||||
var (maxCount, currentlyExecuting, available) = usageTracker.GetConcurrencyStatus(_token);
|
||||
logger.LogInformation($"Token并发状态: {_token}, 最大: {maxCount}, 执行中: {currentlyExecuting}, 可用: {available}");
|
||||
|
||||
// 等待获取并发许可,并且新增当前并发计数
|
||||
_concurrencyAcquired = await usageTracker.WaitForConcurrencyPermitAsync(_token);
|
||||
if (!_concurrencyAcquired)
|
||||
{
|
||||
logger.LogWarning($"Token并发限制超出: {_token}, 并发限制: {tokenConfig.ConcurrencyLimit}");
|
||||
context.Result = new ObjectResult($"Concurrency limit exceeded (max: {tokenConfig.ConcurrencyLimit})")
|
||||
{
|
||||
StatusCode = StatusCodes.Status429TooManyRequests
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
logger.LogInformation($"Token验证成功,开始判断日限制,开始处理请求: {_token}, 并发限制: {tokenConfig.ConcurrencyLimit}");
|
||||
|
||||
// 使用新的原子方法:
|
||||
if (tokenConfig.DailyLimit > 0)
|
||||
{
|
||||
// 原子操作:检查并增加
|
||||
if (!usageTracker.CheckAndIncrementUsage(_token, tokenConfig.DailyLimit))
|
||||
{
|
||||
logger.LogWarning($"Token日限制已达上限: {_token}, 当前使用: {tokenConfig.DailyUsage}, 限制: {tokenConfig.DailyLimit}");
|
||||
context.Result = new ObjectResult("Daily limit exceeded")
|
||||
{
|
||||
StatusCode = StatusCodes.Status403Forbidden
|
||||
};
|
||||
// 判断超出日限制,不实际请求,需要释放一下
|
||||
usageTracker.ReleaseConcurrencyPermit(_token);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 无日限制,直接增加计数
|
||||
usageTracker.IncrementUsage(_token);
|
||||
}
|
||||
|
||||
// 将新token存储在HttpContext.Items中
|
||||
context.HttpContext.Items["UseToken"] = tokenConfig.UseToken;
|
||||
context.HttpContext.Items["RequestToken"] = _token;
|
||||
|
||||
// 再执行请求之前就新增使用计数,再请求之后,判断是不是成功请求,如果失败就释放
|
||||
tokenService.IncrementUsage(_token);
|
||||
|
||||
// 执行 Action
|
||||
var executedContext = await next();
|
||||
|
||||
var shouldRelease = false;
|
||||
// 检查是否需要释放许可
|
||||
var shouldRelease = executedContext.HttpContext.Items.ContainsKey("ReleaseConcurrencyPermit");
|
||||
if (executedContext.HttpContext.Items.TryGetValue("ReleaseConcurrencyPermit", out var permitValue))
|
||||
{
|
||||
// 键存在,permitValue 包含实际值
|
||||
shouldRelease = true;
|
||||
// 可以使用 permitValue 变量
|
||||
}
|
||||
else
|
||||
{
|
||||
// 键不存在
|
||||
shouldRelease = false;
|
||||
}
|
||||
|
||||
// 需要释放,直接释放并发许可
|
||||
if (executedContext.HttpContext.Response.StatusCode >= 400 || shouldRelease)
|
||||
|
||||
Reference in New Issue
Block a user