fix: 优化并发计数过期清理

This commit is contained in:
shaw
2025-10-12 13:14:15 +08:00
parent e337d1fb43
commit a58d67940c

View File

@@ -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')