Cinci erori critice de integrare API la pornire
Eroare # 1. Fără idempotență și „furtună” de retrageri
Simptome: comenzi duplicate/plăți, discrepanță în sume, retururi disputate, alerte DLQ sunt în creștere.
Rădăcină: livrarea repetată a cererilor/cârligelor web și a flappy-urilor de rețea sunt normale. Dacă operațiunea „creare/anulare” nu este idempotentă, retroactivele înmulțesc daunele.
Cum să
Idempotency-Key/' operation _ id' la toate metodele nesigure (POST/PATCH).
Index unic în baza de date pentru "operation _ id'. Reluare - returnați rezultatul anterior.
Webhooks prin tabelul Inbox (dedupe by 'event _ id + signature'). Evenimente de ieșire - Outbox.
Retrai: maxim 1-2 ori, exponent + jitter, numai pentru operațiuni sigure.
Convenția HTTP (exemplu):http
POST/v1/plăți
Cheie Idempotency: ik_f35a2
Tip de conținut: aplicație/json
{"sumă": 5000 ", monedă": "EUR", "sursă": "card_..."}sql
PLĂȚILE ALTER TABLE ADAUGĂ CONSTRÂNGERE uniq_op UNIC (operation_id);python pentru i în intervalul (2):
încercați: retur call_api (sarcină utilă, timeout = 0. 6)
cu excepția Timeout:
somn (0. 05 2i + aleatoriu. uniformă (0, 0. 05))
ridica UpstreamIndisponibil- Toate "monetar/crearea" logica are "operation _ id' and uniq index.
- Inbound webhooks numai prin Inbox cu lucrător idempotent.
- SDK client setează automat Idempotency-Key.
Numărul de eroare 2. Termene/Retrout vs. SLO: Dependență Supraîncălzire
Simptome: p95 plutește brusc, cozile cresc, întrerupătorul de circuit „breton”.
Rădăcină: SLO-ul total al răspunsului este de 400-600 ms, iar termenele la API-urile externe sunt de 1-2 s și chiar se retrag × 3. Faci mai mult decât poţi şi iei cu asalt dependenţa cu repetiţii.
Cum să
Calendarul bugetar: dacă SLO este de 400 ms, intervalul de timp în amonte: 250-300 ms; Total timeout de SLO ≤ cerere.
Limite/Backpressure: semafoare/worker-pool pentru apeluri la fiecare dependență. Aglomerat → 429/503 simultan.
Întrerupător de circuit: „deschis” cu timeout/5xx, „jumătate deschis” dozat.
Controlul admiterii: restricționați concurența (per fir, per punct final/PSP).
Exemplu (Du-te):go sem: = make (chan struct {}, 64 )//limită de competiție la PSP fung callPSP (context ctx. Context, req Req) (Res, eroare) {
selectați {
case sem <- struct {} {}:
defer funcc () {<-sem} ()
c, anulează: = context. WithTimeout (ctx, 300time. Millisecond)
amânare anulare ()
întoarce psp. Do (c, req)
implicit:
return Res {}, ErrBusy//eșec imediat în loc de coadă nesfârșită
}
}- Timeout-urile sunt mai scurte decât SLO; retrai ≤ 2; Nu este Jitter.
- Piscine/semafoare la API-uri externe; întrerupător de circuit cu metrici.
Pe rutele aglomerate, ne întoarcem 429/Retry-After, nu păstrăm conexiuni.
Numărul de eroare 3. Securitate slabă: semnături, secrete, TLS
Simptome: webhookurile „altor persoane” trec, secretele din cod/jurnal, riscurile MITM.
Rădăcină: nici o verificare a semnăturii/prospețimii, secretele trăiesc în fișiere env, TLS vechi și antete slabe.
Cum să
Semnătura cârligelor web HMAC-SHA256 + 'X-Timestamp' (fereastră ≤ 5-10 minute), compararea strictă a semnăturii.
mTLS pentru integrări critice sau IP allow-list.
Rotirea secretelor prin Vault/Cloud KMS; drepturi minime; audit de scădere.
TLS 1. 2/1. 3 numai, HSTS, CORS corect (lista sursă îngustă).
Verificarea semnăturii (Python):python def verifică (sig_hdr, ts_hdr, corp, secret):
dacă ABS (timp. timp () - int (ts_hdr))> 600: raise Expirat ()
calc = hmac. nou (secret, (ts_hdr + „.” + corp). codifică (), hashlib. sha256). hexdigest ()
dacă nu hmac. compare_digest (calc, sig_hdr): raise BadInsp ()- Toate cârligele web sunt semnate și verificate; fereastra de prospețime este limitată.
- Secretele în KMS/Vault, există rotație și audit.
- TLS/HSTS activat; punctul CORS; IP/mTLS, dacă este cazul.
Numărul de eroare 4. Deriva contractului: schema „și-a trăit viața”
Simptome: prod a căzut „numai la unii clienți”, 500/422 în jurnalele, diferite versiuni ale argumentează SDK și API.
Rădăcină: nu există o descriere strictă a contractelor, schimbări incompatibile înapoi, câmpuri „liniștite”, sensuri diferite pentru aceleași nume.
Cum să
Contract-primul: OpenAPI/AsyncAPI + server/generare client; pentru evenimente - Avro/Protobuf + Schema Registry.
Versioning: 'v1 → v2' (URI/header), deviation-plan, grace-period.
Înapoi-compat: numai modificări aditive în versiuni minore; nu poate fi șters/redenumit fără v-cucui.
Testele contractuale: Pact/Buf - furnizor/consumator sunt testate în CI.
Exemple:yaml
OpenAPI: tip clar de sumă în unități amount_minor minore:
tip: număr întreg minim: 0 descriere: Sumă în unități monetare minime (număr întreg)- Contractele sunt stocate în git, CI validează/întrerupe dacă sunt incompatibile.
- Schema se înregistrează pentru evenimente, compatibilitate „înapoi/înainte”.
- Pagina de andocare a modificărilor, datele de depriciere, bancul de testare pentru parteneri.
Numărul de eroare 5. Lansarea „Blind”: fără valori/jurnale/trasee și nisip
Simptome: „nimic nu este vizibil”, sprijin umple, debag - mâini în prod.
Rădăcină: observabilitatea nu a fost inclusă, nu există sintetice, cutia de nisip a fost testată „în cuvinte”.
Cum să
Valorile RED/USE: rată/eroare/latență pe fiecare punct final, pe traseu/metodă.
Corelație: 'trace _ id' în toate jurnalele și răspunsurile; un pachet de zapros↔vebkhuk.
Sintetice: teste de sănătate (login/depozit nisip), SLA de monitorizare T + 60 pentru webhooks.
Sandbox/etapă: chei/domenii complet izolate, PSP-uri fictive, intrări „neincluse în rapoarte”.
Răspuns cu ID de urme:http
HTTP/1. 1 202 Acceptat
Trace-Id: 7f2b3d8e9c1a4
Location: v1/ops/req_42/status- RED/UTILIZAȚI metrici, tablouri de bord, alerte (simptome + cauze).
- Trasee end-to-end; Jurnalele JSON, fără PII, cu 'trace _ id'.
- Sintetice din regiuni cheie; sandbox este necesar, chei diferite.
Planul de prelansare (T-7 → T-0)
T-7 zile:- Scanarea finală a contractului: există modificări incompatibile; blochează schemele.
- Secretele/Certificatele: verificarea rotației, accesele, politicile KMS.
- Sintetice 24 × 7, alerte sunt legate de la apel.
- Încărcare mini-run (izbucnire 2-5 minute): p95/piscine/cozi în zona verde.
- Cârlige DRY-RUN (reluări, 5xx, jitter), verificare DLQ.
- „Cartea de telefon” a partenerilor: contacte L1/L2, canal de război.
- Trafic de canale 5% → 25% → 50% pentru porțile SLO; gata rollback.
- Kill-switch/feature-steaguri pe caracteristici riscante sunt incluse.
- Camera de război este activă, șabloanele de stare sunt pregătite.
Planul Rollback (dacă ceva nu a mers bine)
1. Eliberați traficul la versiunea stabilă/traseul anterior.
2. Dezactivați modificările controversate ale phicheflag-ului.
3. Stabilizați cozile/piscinele, opriți retragerile într-o furtună.
4. Post-incident: colecta cronologie, rădăcini, sarcini (fixe înainte/fixe contract).
Începeți tabelul de auto-testare (scurt)
Întrebat frecvent „ce se întâmplă dacă”...
... furnizorul nu acceptă Idempotency-Key?
Stocați 'hash (body)' + 'partner _ request _ id' și introduceți idempotența.
... cârlige uneori vin „înainte” răspunsul?
Coase pe "operation _ id' și să păstreze temporar" necunoscut → reconcilia "stare; reconcilierul periodic va închide discrepanțele.
... necesitatea de a sprijini clienții vechi și noi?
Versiunea punctelor finale ('/v1 'și '/v2'), traseul cu antetul/URI, păstrează compatibilitatea înapoi timp de cel puțin N luni.
Rezumat reluare
Eșecurile de integrare sunt aproape întotdeauna aproximativ același lucru: fără idempotență, temporizări și retrageri greșite, semnarea slabă a cârligelor web, deriva contractuală și lipsa vizibilității. Fixați contractele în avans, activați observabilitatea, plasați limite/backprescher, semnați toate interacțiunile externe și rulați sintetice. Apoi, chiar și în cazul eșecurilor partenerilor, eliberarea dvs. va rămâne gestionabilă - fără bani pierduți în retras și fără o noapte nedormită pentru întreaga echipă.
