五个关键的API启动集成错误
错误1。No Idementity and "Storm" Retrae
症状:订单/付款单、金额差异、有争议的退款、DLQ异序上升。
根:重新交付查询/webhook和网络flappi-正常。如果"创建/注销"操作不是偶然的,则retrai会增加损坏。
如何正确
Idempotency-Key/'operation_id'对所有不安全方法(POST/PATCH)。
通过"operation_id"在DB中唯一索引。重播-返回过去的结果。
Webhooks通过Inbox表("event_id+signature"上的dedupe)。出站事件是Outbox。
Retrai:最多1-2次,参展商+jitter,仅用于安全操作。
HTTP约定(示例):http
POST /v1/payments
Idempotency-Key: ik_f35a2
Content-Type: application/json
{"amount": 5000, "currency": "EUR", "source": "card_..."}sql
ALTER TABLE payments ADD CONSTRAINT uniq_op UNIQUE (operation_id);python for i in range(2):
try: return call_api(payload, timeout=0.6)
except Timeout:
sleep(0.05 2i + random.uniform(0, 0.05))
raise UpstreamUnavailable- 所有"货币/创建"逻辑都具有"operation_id"和uniq索引。
- 仅通过Inbox与Idempotent Worker收件箱收件箱。
- 客户端SDK自动设置Idempotency-Key。
错误2。超时/中继对SLO: 依赖性的"过热"
症状:p95突然漂浮,队列上升,巡回休息员"飞溅"。
根:通用响应SLO为400-600毫秒,而外部API的超时时间为1-2秒,至今仍为3 ×。你做的时间比你能做的时间长,并且通过重复来攻击成瘾。
如何正确
预算时间:如果SLO 400毫秒,则上游超时:250-300毫秒;请求的总超时时间≤ SLO。
Limits/Backpressure:每个依赖项的调用信号灯/工作池。429/503 →立即溢出。
巡回赛决胜局:在超时/5xx处处于"开放"状态,"半开放"处方。
管理控制:限制并行(每个线程,在endpoint/PSP)。
示例(Go):go sem:=make(chan struct{},64)//竞争限制PSP func callPSP(ctx context。Context, req Req) (Res, error) {
select {
case sem <- struct{}{}:
defer func(){ <-sem }()
c, cancel:= context.WithTimeout(ctx, 300time.Millisecond)
defer cancel()
return psp.Do(c, req)
default:
return Res{},ErrBusy/立即拒绝代替没有结束的队列
}
}- 超时时间短于SLO;retrai ≤ 2;有一个摇摆人。
- 外部API的池/信号器;带有度量的电路断路器。
- 在"繁忙"路线上,我们返回429/Retry-After而不是保持连接。
错误3。弱安全性: webhook签名,秘密,TLS
症状:"陌生人"webhooks通过,密码/博客中的秘密,MITM风险。
根:没有签名/新鲜度检查,env文件中存在秘密,旧TLS和弱头。
如何正确
Webhooks签名HMAC-SHA256+'X-Timestamp'(窗口≤ 5-10分钟),严格的签名比较。
用于关键集成或IP allow-list的mTLS。
通过Vault/Cloud KMS轮换秘密;最低限度的权利;减法审核。
TLS 1.2/1.3 only,HSTS,正确的CORS(窄源列表)。
签名验证(Python):python def verify(sig_hdr, ts_hdr, body, secret):
if abs(time.time() - int(ts_hdr)) > 600: raise Expired()
calc = hmac.new(secret, (ts_hdr + "." + body).encode(), hashlib.sha256).hexdigest()
if not hmac.compare_digest(calc, sig_hdr): raise BadSig()- 所有webhooks均已签名并经过验证;清新窗口是有限的。
- KMS/Vault的秘密,有轮换和审计。
- TLS/HSTS包括在内;CORS点点;IP/mTLS在适当时。
错误4。合同漂移: 计划"过着自己的生活"
症状:prod"仅在部分客户中"下降,在日志中下降500/422,不同版本的SDK和API争论不休。
根: 没有严格的合同描述,背面不兼容的更改,"安静"的字段,不同的含义在相同的标题.
如何正确
合同一:OpenAPI/AsyncAPI+服务器/客户端生成;活动-Avro/Protobuf+Schema Registry。
转化:"v1 → v2"(URI/头部),deprecation计划,grace时期。
Backward-compat:仅对次要版本进行附加更改;禁止删除/重命名而不使用v-bump。
合同测试:Pact/Buf-提供商/领事在CI进行验证。
示例:yaml
OpenAPI:amount_minor次要单位中的清晰和类型:
type: integer minimum: 0 description:以货币最低单位计算的总和(整数)- 合同存储在git中,CI在不兼容时验证/断开。
- 事件模式寄存器,"back/forward"兼容性。
- 更改坞页、剥离日期、合作伙伴测试台。
错误5。"盲人"发射: 没有指标/标志/预告片和沙箱
症状:"什么都看不见",支持被淹没,debag被卖掉。
根:不包括观察力,没有合成物,沙盒被"言语"测试。
如何正确
RED/USE度量标准:rate/error/latency在每个endpoint,路线/方法。
相关性:所有逻辑和答案中的"trace_id";zapros↔vebkhuk韧带。
合成:健康样本(login/deposit-sand),webhooks的T+60 SLA监测。
沙箱/站点:完全隔离的钥匙/域,虚构的PSP,记录"不属于报告"。
使用trace ID的响应:http
HTTP/1.1 202 Accepted
Trace-Id: 7f2b3d8e9c1a4
Location: /v1/ops/req_42/status- RED/USE度量标准,dashbords,alerta(症状+原因)。
- 终结轨道;JSON logs,没有PII,带有"trace_id"。
- 主要区域的合成品;沙箱是强制性的,钥匙是不同的。
Prelounch计划(T-7 → T-0)
T-7天:- 最终合同扫描:是否没有不兼容的更改;冻结电路。
- 秘密/证书:检查轮换、访问、KMS策略。
- 合成24 × 7,Alertes绑在电话上。
- 负荷迷你运行(burst 2-5 min): p95/池/绿区队列。
- DRY-RUN webhook(重播,5xx,jitter),DLQ检查。
- 合作伙伴的"电话簿":L1/L2联系人,战争室频道。
T-0:
SLO门的金丝雀流量为5% → 25% → 50%;已准备好回滚。
包括基于风险码头的杀手-switch/feature-flags。
战争室处于活动状态,准备了模板状态。
Rollback计划(如果出了问题)
1.删除到先前稳定版本/路线的流量。
2.禁用ficheflagom有争议的更改。
3.稳定队列/池,在"暴风雨"中停止撤退。
4.后事件:收集时间线,根,任务(虚构前锋/合同小说)。
启动自检表(短)
常见问题"如果……怎么做"
……提供商不支持Idempotency-Key?
储存'hash (body)'+'partner_request_id'并输入您的等效性。
……webhooks有时"提前"回答?
按"operation_id"缝合,暂时保持"未知→重新发现"状态;定期reconciler将关闭差异。
……需要支持老客户和新客户吗?
转化endpoint 's ('/v1'和'/v2'), 通过标题/URI进行路由,保持最少N个月的后端兼容性。
二.总结
集成的失败几乎总是相同的:没有幂等性,超时和后退,webhook签名弱,合同漂移和缺乏可见性。预先确定合同,启用可观察性,放置限制/becpresher,签署所有外部交互并启动合成。然后,即使合作伙伴失败,您的版本仍然可以管理-没有在后台丢失的钱,也没有整个团队的不眠之夜。
