mirror of
https://github.com/Wei-Shaw/claude-relay-service.git
synced 2026-01-22 16:43:35 +00:00
fix: 优化并发计数过期清理
This commit is contained in:
71
src/app.js
71
src/app.js
@@ -556,6 +556,62 @@ class Application {
|
||||
logger.info(
|
||||
`🚨 Rate limit cleanup service started (checking every ${cleanupIntervalMinutes} minutes)`
|
||||
)
|
||||
|
||||
// 🔢 启动并发计数自动清理任务(Phase 1 修复:解决并发泄漏问题)
|
||||
// 每分钟主动清理所有过期的并发项,不依赖请求触发
|
||||
setInterval(async () => {
|
||||
try {
|
||||
const keys = await redis.keys('concurrency:*')
|
||||
if (keys.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
const now = Date.now()
|
||||
let totalCleaned = 0
|
||||
|
||||
// 使用 Lua 脚本批量清理所有过期项
|
||||
for (const key of keys) {
|
||||
try {
|
||||
const cleaned = await redis.client.eval(
|
||||
`
|
||||
local key = KEYS[1]
|
||||
local now = tonumber(ARGV[1])
|
||||
|
||||
-- 清理过期项
|
||||
redis.call('ZREMRANGEBYSCORE', key, '-inf', now)
|
||||
|
||||
-- 获取剩余计数
|
||||
local count = redis.call('ZCARD', key)
|
||||
|
||||
-- 如果计数为0,删除键
|
||||
if count <= 0 then
|
||||
redis.call('DEL', key)
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
`,
|
||||
1,
|
||||
key,
|
||||
now
|
||||
)
|
||||
if (cleaned === 1) {
|
||||
totalCleaned++
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`❌ Failed to clean concurrency key ${key}:`, error)
|
||||
}
|
||||
}
|
||||
|
||||
if (totalCleaned > 0) {
|
||||
logger.info(`🔢 Concurrency cleanup: cleaned ${totalCleaned} expired keys`)
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('❌ Concurrency cleanup task failed:', error)
|
||||
}
|
||||
}, 60000) // 每分钟执行一次
|
||||
|
||||
logger.info('🔢 Concurrency cleanup task started (running every 1 minute)')
|
||||
}
|
||||
|
||||
setupGracefulShutdown() {
|
||||
@@ -583,6 +639,21 @@ class Application {
|
||||
logger.error('❌ Error stopping rate limit cleanup service:', error)
|
||||
}
|
||||
|
||||
// 🔢 清理所有并发计数(Phase 1 修复:防止重启泄漏)
|
||||
try {
|
||||
logger.info('🔢 Cleaning up all concurrency counters...')
|
||||
const keys = await redis.keys('concurrency:*')
|
||||
if (keys.length > 0) {
|
||||
await redis.client.del(...keys)
|
||||
logger.info(`✅ Cleaned ${keys.length} concurrency keys`)
|
||||
} else {
|
||||
logger.info('✅ No concurrency keys to clean')
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('❌ Error cleaning up concurrency counters:', error)
|
||||
// 不阻止退出流程
|
||||
}
|
||||
|
||||
try {
|
||||
await redis.disconnect()
|
||||
logger.info('👋 Redis disconnected')
|
||||
|
||||
Reference in New Issue
Block a user