一、退避与抖动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)
}
二、幂等与计数头type Req = { headers: Record<string, string | undefined> }
type Res = { setHeader: (k: string, v: string) => void; status: (n: number) => Res; end: (b?: string) => void }
function validIdem(k: string): boolean { return /^[A-Za-z0-9_\-\.]{8,128}$/.test(k) }
三、重试封装type Task = () => Promise<Response>
async function safeRetry(task: Task, attempts: number, baseMs: number, maxMs: number, onAttempt?: (i: number, delayMs: number) => void): Promise<Response> {
let last: any
for (let i = 0; i < attempts; i++) {
try {
const r = await task()
if (r.status < 500 && r.status !== 429) return r
const retryAfter = Number(r.headers.get('Retry-After') || '0')
const delay = retryAfter > 0 ? retryAfter * 1000 : backoff(baseMs, i, maxMs)
onAttempt?.(i + 1, delay)
await new Promise(res => setTimeout(res, delay))
last = r
} catch (e) {
const delay = backoff(baseMs, i, maxMs)
onAttempt?.(i + 1, delay)
await new Promise(res => setTimeout(res, delay))
last = e
}
}
throw last
}
四、服务端协同function setRetryHeaders(res: Res, retryAfterSec: number, count: number) {
res.setHeader('Retry-After', String(retryAfterSec))
res.setHeader('X-Retry-Count', String(count))
}
五、整合与验收指数退避与抖动限制雪崩;遵循`Retry-After`优先;最大延迟与尝试次数受控。幂等键校验与计数头可用;与断路器/速率限制协同避免级联失败。审计记录包含尝试次数与延迟;失败策略清晰(>=500或429重试)。

发表评论 取消回复