重复和备份策略
重播(retries)有助于在时间故障中幸存下来,但是如果设置不当,则会导致流量雪崩、操作重复和级联下降。可靠的撤退政策总是从截止日期/时间开始,考虑幂等性,并使用backoff+jitter。
1)基本原则
1.首先是定时/截止日期,然后是转发。没有时间限制的重播只会延长故障。
2.Retray-仅用于安全/等效操作。对于不安全的-通过idempotency-keys和事务性保修。
3.Backoff是强制性的。指数或GCRA样的Jitter以同步波。
4.限制尝试次数和总预算时间。不要为用户的SLO退出。
5.尊重基础设施信号。"429/503"+"Retry-After",电路中断器的状态,队列限制。
2)Taymauts和截止日期(截止日期)
请求定时<SLO服务,截止日期沿链传播(HTTP 标题/gRPC context)。
Taymauts的组成:总计(第一次尝试+backoff+以后)≤自定义的截止日期。
阅读/记录的不同时间:记录更短,更严格;读数允许拼写。
3)相似性和安全重播
阅读(GET/IDEMPC):在"5xx"、"UNAVAILABLE"、网络时间表中安全重复。
记录:- 在边界上使用"Idempotency-Key"(HTTP)或request-ID;服务器必须进行重复数据消除。
- 写出等效处理程序:"upsert","at-least-once"+补偿(传奇)。
- 外部付款/互惠-仅具有偶数密钥和运营日志。
4)backoff算法
Exponential:"base 2^attempt",限于"max_backoff"。
Decorrelated Jitter (full/equal jitter):用于客户端同步的范围随机性。
GCRA/Token-Bucket之类的延迟:与等级限制一致。
边界:"initial_backoff"(50-200毫秒阅读;200-500 ms记录),"max_backoff"(1-5 s),"max_elapsed"(例如3-10 s)。
推荐模板:指数backoff+full jitter。
5)决定"重复/不重复"的政策"
我们在以下方面重复:- 网络错误/时间限制,"429"(尊重'Retry-After'),"软""5xx"("502/503/504"),gRPC "UNAVAILABLE/DEADLINE_EXCEED"。
- "4xx"(某些脚本中的"409/429/408"除外),业务错误,"401/403",验证错误,显然是"DoNotRetry"标志。
- '409 Conflict'-有时在共识/锁定后延迟重播。
- eventually consistent reading的"404"是带有小背景的一到两倍的回程。
6)Concurrency caps和"暴风雨撤退"
限制同步per-client/per-tenant/per-endpoint中继。
请求尝试的总限制(例如2-3)。
通过管理控制来制动"热"结束点,以免排队。
7)与Circuit Breaker和限制互动
如果CB打开,请不要直接执行retrai-返回或等待"半打开"样本。
在"429"-尊重"Retry-After";如果没有它-应用"软"backoff。
Retrai可以增加负载;应用自适应阈值(在事件中降低"max_attempts")。
8)协议和合同
HTTP
编码:"408/429/5xx"。
标题:"Retry-After","RateLimit-"家族,"Idempotency-Key","Request-Id"。
客户必须发送"X-Request-Timeout"/"Deadline-At"(如果接受的话)。
gRPC
使用截止日期上下文;尊重"UNAVAILABLE","DEADLINE_EXCEED",每种方法的复制品。
对于幂等的RPC-包括复古;对于突变-仅支持幂等。
9)队列、背景任务和集成
One-least-once处理程序→等效操作、按键重复数据消除。
延迟时间用于尝试之间的后退(例如5s/30 s/2m)。
Dead-letter queue(DLQ)具有尝试和手动处理限制。
Outbox/CDC-确保重播不会破坏事务完整性。
10) Hedging vs Retries
Hedging(镜像查询)对于尾部潜伏期的高临界读数很有用。
限制:不多于X%的查询,延迟的"开始格雷斯"(例如p95潜伏期),取消失败者。
不要在没有强幂等性的情况下将刺痛应用于写入操作。
11)遥测和可观察性
Теги: `tenant_id`, `endpoint`, `attempt`, `decision` (retry/skip), `reason`, `backoff_ms`, `deadline_ms`, `idempotency_key`.
度量标准:中继比例,中继后成功,p95/p99"端到端",超过截止日期的数量,CB触发。
审计记录:"嘈杂"键的顶部N/尾部,与429/503相关。
12)测试和溷乱
轮廓为:"pila"(暴风雨),"storm"(大量taymauts),"粘性"错误(每个N-),潜伏尾巴。
限量/缓存/队列堆栈故障,clock-skew。
检查总持续时间(attempts+backoff)是否适合于SLO。
13)政策伪代码
pseudo handle(req, deadline):
attempt = 0 backoff = initial()
while attempt < MAX_ATTEMPTS and now() < deadline:
attempt += 1 with timeout(per_attempt_timeout(deadline, attempt)):
try:
resp = call(req)
if isRetryableStatus(resp): raise Retryable(resp. status)
return resp except Retryable as e:
if circuit. isOpen(dep) or! isIdempotent(req): break sleep(jitter(backoff))
backoff = min(exp(backoff), MAX_BACKOFF)
except NonRetryable:
break return fail_or_fallback(req)
14)配置模板(示例)
yaml retries:
default:
max_attempts: 3 initial_backoff_ms: 150 max_backoff_ms: 2000 strategy: exponential_full_jitter respect_retry_after: true per_attempt_timeout_fraction: 0. 4 # 40% of remaining deadline hedging:
enabled: false read_heavy:
max_attempts: 4 initial_backoff_ms: 80 max_backoff_ms: 1200 hedging:
enabled: true start_after_p95_ms: 300 max_extra_requests_ratio: 0. 05 write_strict:
max_attempts: 2 initial_backoff_ms: 250 max_backoff_ms: 1000 idempotency_required: true
limits:
concurrent_retries_per_tenant: 100 concurrent_retries_per_endpoint: 20
15)售前支票清单
- 截止日期通过挑战传播;总持续时间≤ SLO。
- 具有抖动的反向算法;参数由负载测试验证。
- 相同性:记录/日志/补偿。
- Retray政策在阅读和记录方面有所不同;respect `Retry-After`.
- 中继器的竞争性和尝试总数是有限的。
- 与circuit breaker和rate limits的集成已配置。
- 遥测:标签,度量,原因逻辑;dashbords p95/p99,回程后的成功率。
- 测试"风暴"和潜伏尾巴,任务的DLQ。
- 客户文档:代码/标题,后退和取消示例。
16)典型错误
没有时间线/截止线的重播是"永恒的期望"。
没有喷射器的固定暂停是同步波和DDoS自处理。
不安全的录音的复制品没有同步-双重和同步。
忽视"Retry-After"和CB信号是事件的升级。
由于缺少caps和管理控制,队列中的瓶颈。
缺乏原因遥测/撤退解决方案是"盲目飞行"。
17)快速食谱
公开阅读API:3次尝试,'initial=100 ms','max=1s',full jitter,高达5%的流量。
关键记录(付款):1-2次尝试max,严格的计时器,强制性的"Idempotency-Key",没有抱怨。
外部集成:尊重"429/Retry-After","max_attempts=3","max_backoff=2-5s",出站流限制。
背景任务:delay-backoff (5 s → 30 s → 2m), DLQ,等效处理程序。
结论
良好的重播策略是快速恢复和受控故障之间的平衡。截止线,等效性,带有抖动的指数反射,限制竞争和对基础设施信号的尊重将从"风暴"转变为提高SLO可靠性和保留性的工具。