背景与价值后台队列易出现重复与泄漏。统一重试、去重与TTL策略可保障稳定与可控。统一规范去重:基于任务键与窗口去重。重试:指数退避与上限控制,记录尝试数。泄漏防护:TTL到期清理,超时任务回收。核心实现队列与去重type Job = { id: string; key: string; payload: any; attempts: number; ttlMs: number; enqueuedAt: number } class Queue { list: Job[] = [] seen = new Map<string, number>() now(): number { return Date.now() } enqueue(key: string, payload: any, ttlMs = 600000): Job | null { const last = this.seen.get(key) || 0 if (this.now() - last < 30000) return null const j: Job = { id: Math.random().toString(36).slice(2), key, payload, attempts: 0, ttlMs, enqueuedAt: this.now() } this.list.push(j) this.seen.set(key, this.now()) return j } dequeue(): Job | undefined { const j = this.list.shift(); return j } cleanup() { this.list = this.list.filter(j => this.now() - j.enqueuedAt <= j.ttlMs) } } 重试与退避function backoff(baseMs: number, attempt: number, maxMs: number): number { const exp = Math.min(maxMs, baseMs * Math.pow(2, attempt)); const jitter = Math.random() * exp * 0.5; return Math.floor(exp * 0.75 + jitter) } async function runJob(job: Job, handler: (p: any) => Promise<void>, baseMs = 100, maxMs = 5000, maxAttempts = 5): Promise<boolean> { let ok = false for (let i = 0; i < maxAttempts; i++) { try { await handler(job.payload); ok = true; break } catch { const delay = backoff(baseMs, i, maxMs); await new Promise(r => setTimeout(r, delay)); job.attempts++ } } return ok } 落地建议为后台任务引入去重窗口与TTL治理,避免重复与泄漏。使用指数退避与尝试上限,记录尝试数用于审计与优化。验证清单同键任务是否在窗口内去重;TTL到期是否清理;重试是否有上限与退避。

发表评论 取消回复