feat: 优化并发控制和移除冗余限制功能

主要改进:
1. 改进并发控制机制
   - 使用 once 代替 on 避免重复监听
   - 监听多个事件确保可靠性(close、finish)
   - 支持客户端断开时立即释放并发槽位

2. 支持非流式请求的客户端断开处理
   - 客户端断开时立即中断上游请求
   - 避免资源浪费和不必要的 API 调用

3. 移除 requestLimit(请求数限制)功能
   - 移除配置和验证逻辑
   - 保留请求统计用于监控分析

4. 移除速率限制(Rate Limit)功能
   - 移除 RATE_LIMIT_* 配置
   - 简化中间件逻辑
   - 避免与并发控制重复

现在系统仅保留:
- Token 使用量限制
- 并发数限制(更精确的资源控制)

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
shaw
2025-07-16 14:40:37 +08:00
parent f9bc2ddb23
commit 567e3b25aa
9 changed files with 62 additions and 108 deletions

View File

@@ -45,20 +45,7 @@ router.post('/v1/messages', authenticateApiKey, async (req, res) => {
res.setHeader('Connection', 'keep-alive');
res.setHeader('Access-Control-Allow-Origin', '*');
// 流式响应添加客户端断开检测,确保并发计数正确减少
if (req.concurrencyInfo) {
// 添加响应关闭事件监听器
res.on('close', () => {
logger.api(`🔌 Stream response closed for key: ${req.apiKey.id} (${req.apiKey.name}), triggering concurrency decrement`);
req.concurrencyInfo.decrementConcurrency();
});
// 添加错误事件监听器
res.on('error', (error) => {
logger.api(`⚠️ Stream response error for key: ${req.apiKey.id} (${req.apiKey.name}): ${error.message}`);
req.concurrencyInfo.decrementConcurrency();
});
}
// 流式响应不需要额外处理,中间件已经设置了监听器
let usageDataCaptured = false;
@@ -99,7 +86,7 @@ router.post('/v1/messages', authenticateApiKey, async (req, res) => {
apiKeyName: req.apiKey.name
});
const response = await claudeRelayService.relayRequest(req.body, req.apiKey);
const response = await claudeRelayService.relayRequest(req.body, req.apiKey, req, res);
logger.info('📡 Claude API response received', {
statusCode: response.statusCode,
@@ -201,7 +188,6 @@ router.get('/v1/key-info', authenticateApiKey, async (req, res) => {
id: req.apiKey.id,
name: req.apiKey.name,
tokenLimit: req.apiKey.tokenLimit,
requestLimit: req.apiKey.requestLimit,
usage
},
timestamp: new Date().toISOString()
@@ -224,7 +210,7 @@ router.get('/v1/usage', authenticateApiKey, async (req, res) => {
usage,
limits: {
tokens: req.apiKey.tokenLimit,
requests: req.apiKey.requestLimit
requests: 0 // 请求限制已移除
},
timestamp: new Date().toISOString()
});