GH GambleHub

Tekrarlama stratejileri ve idempotency

1) Neden ihtiyacınız var

Ağlarda, arızalar normdur: zaman aşımları, geçici hatalar, ağ flappingleri, aşırı yük. Geri çekilmeler yalnızca aşağıdaki durumlarda güvenilirliği artırır:

1. Güvenli tekrarlayın (idempotent),

2. Tekrarlar arasındaki gecikmeler gözlenir,

3. sınırlara/kotalara ve bağımlılıklara'sağlık "saygı gösterilir.

Amaç, bir kez etkili bir şekilde, yanlış alımlar ve yarışlar olmadan iş operasyonları düzeyinde davranıştır.

2) Teslimat semantiğinin taksonomisi

En çok bir kez: tekrar yok, kayıp riski (günlüğe kaydetme, ateş etme ve unutma).
En az bir kez: kopyalar mümkündür - tüketici idempotence gereklidir (çoğu kuyruk, webhook).
Etkili bir kez: kopyalar mümkündür, ancak doğru şekilde tekilleştirilir (anahtarlar, işlemler, giden kutusu).

3) Ne zaman geri çekilmeli ve ne zaman değil

Geri çekilme mantıklı: '408', '429' ('Retry-After' gözlemleme), '425' (Çok Erken), '499' (istemci çevre üzerinde kapalı), '5xx', '504', ağ zaman aşımları/sonları, ağ geçidinde '502', 'bağlantı sıfırlama'.
Sorguyu değiştirmeden geri çekmeyin: '400/ 401/403/404/422'.
Tartışmalı durumlar: '409 Çatışma' (genellikle retrayim değil; Önce operasyonun durumunu okuyoruz/niyeti yeniden teyit ediyoruz).

4) Zaman aşımları, backoff ve jitter

4. 1 Kurallar

Önce zaman aşımı, sonra retro: Her isteğin bir "son tarihi" olmalıdır.
Üstel geri dönüş: 'delay _ n = base 2 ^ n', limit 'max _ delay'.
Jitter gereklidir: "donuk senkron dalgaları" ayırmak için rastgelelik ekleyin.

4. 2 Jitter desenleri

Full jitter: 'sleep = rand (0, base2 ^ n)'en iyi genel seçimdir.
Dekore edilmiş jitter: 'Uyku = min (max_delay, rand (taban, sleep_prev3))' - uzun diyaloglar için.
Eşit titreme: 'uyku = base2 ^ n/2 + rand (0, base2 ^ n/2)' - yumuşak varyasyon.

4. 3 Yeniden deneme bütçesi

Retrays oranını sınırlayın:
  • 'retry _ budget _ per _ min = max (α success_rps, kat β)'; Genellikle 'α = 0. 1–0. 2`.
  • Bütçe tükenmişse, hızlı/devre kesici "açık'a geçin.

5) Hız sınırlaması ve Devre Kesici ile etkileşim

'Retry-After', 'RateLimit-Reset'e saygı gösterin ve geri planda sayın.
Yüksek '5xx'/zaman aşımlarında - retray frekansını ve genel eşzamanlılığı düşürün.

Devre kesici:
  • Yarı açık: Sınırlı örneklemeye izin verir.
  • Aç: anında reddeder (kaynak tasarrufu sağlar).
  • Kapalı: Sıradan iş.
  • Yazma işlemlerinde, 409/503'ü büküm agresif retrays yerine net bir ipucu ile döndürmek tercih edilir.

6) Yazma işlemlerinin idempotensi

6. 1 Genel fikir

Aynı niyetler - bir sonuç. Temel, idempotence anahtarı ve yürütme kayıtlarının depolanmasıdır.

6. 2 HTTP sözleşmesi

İstemci başlığı gönderir:

Idempotency-Key: 7a6b7f9e-2a46-4d0b-9c3a-2b30e1c3c9e3
Idempotency-Key-Expiry: 24h # optional
Sunucu:
  • İlk başarıda kaydeder (anahtar, sonuç - durum, vücut karması)
  • Tekrarlanırsa, eski yanıtı ve 'Idempotency-Replay: true' başlığını döndürür;
  • Bir vücut çatışması durumunda (aynı anahtar, ancak farklı bir yük) - '409 Çatışma'.

6. 3 Depolama ve TTL

Tablo/değer anahtarı: 'idempotency _ key', 'request _ hash', 'result', 'status', 'expiry _ at'.
TTL = olası tekrarlar ve geç teslimatlar penceresi (ödemeler için genellikle 24-72 saat).
'Idempotency _ key'ile endeksler; Yüksek yük için - hash sharding.

6. 4 Örnek Şema (SQL)

sql
CREATE TABLE idempo_store (
key UUID PRIMARY KEY,
req_hash BYTEA NOT NULL,
status INT NOT NULL,
response JSONB NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expiry_at TIMESTAMPTZ NOT NULL
);

6. 5 İşleyici pseudocode

pseudo handle_write(req):
k = req. headers["Idempotency-Key"]
h = hash(req. body)
rec = idempo_store. get(k)

if rec and rec. req_hash == h:
return rec. status, rec. response, {"Idempotency-Replay": "true"}

if rec and rec. req_hash!= h:
return 409, problem("IDEMPOTENT_CONFLICT")

begin tx result = apply_business_mutation (req) # change status upsert once (idempo_store, key = k, req_hash=h, status = 201, response = result, expiry = now () + 2d)
commit

return 201, result

7) "etkili-bir kez" desenleri

İşlem Giden Kutusu: Bir iş olayını kaydetmek ve aynı veritabanı işleminden arka plan rölesi aracılığıyla bir mesaj göndermek; Tüketici idempotenttir.
Gelen kutusu/Tüketicide İşlenmiş tablo: kopyaları yoksaymak için 'event _ id' değerini kaydedin.
Tam olarak bir kez Kafka'da ≠ tam olarak bir kez iş dünyasında: Üretici/tüketici EOS ile bile, uygulanan mantık hala idempotent olmalıdır.
Telafi edici işlemler (Saga): Adımlar geri çekilirse ve yan etkilere neden olursa, sistemi değişmeze geri döndürürüz.

8) Özel durumlar: ödemeler ve finansal işlemler

Güçlü idempotency: Anahtar çalışma mantığına bağlıdır (örn. 'dış _ ödeme _ id').
PSP'de veri tekilleştirme - Mağaza 'merchant _ reference' - tekrarlanırsa, PSP aynı sonucu döndürür.
Retrays "istemciden": Yalnızca 'Idempotency-Key' olduğunda izin verin, aksi takdirde çift yazma riski.
Rekabet: Yürütme süresi boyunca "hesapta/araçta/sözleşmede" kilitler; Tekrarlandığında, 409/423 döndürün.
Gözlemlenebilirlik: metrikler 'idempo _ replay _ total', 'idempo _ conflict _ total'.

9) Webhooks ve dış zorluklar

HMAC imzaları ve zaman penceresi; Önce doğrulama, sonra işleme.
Gönderen geri alır: üstel geri alma + jitter, 'max _ trials've DLQ.
Tüketici - idempotent: 'event _ id' - tablo/bellek içi önbellek; "Düzenli" sipariş garanti edilmez.
Kodlar: 2xx = başarılı, 4xx = tekrar etme, 5xx/zaman aşımı = tekrar.

10) Kuyruklar ve arka plan görevleri

Varsayılan olarak en az bir kez - kopyalar kaçınılmazdır.
'Task _ id'/' event _ id've yürütme durumunu saklayın; kopyalarla - kısa yol "yeniden oynatma".
DLQ ve zehir mesajları: sayaç, karantina, manuel ayrıştırma girişimi.
Rekabet limitleri (semaforlar) ve idempotent işçiler.

11) Sürüm oluşturma ve "doğal" anahtarlar

Doğal anahtarlar (hesap numarası + tarih + belge numarası) tekrarlamaya karşı direnci artırır.
Şemayı/sürümü değiştirirken, sürüm anahtarını 'Idempotency-Key' veya sorgu karmasına ekleyin.

12) HTTP başlıkları ve istemciye sorar

'Idempotency-Key', 'Idempotency-Replay', 'Retry-After', 'Prefer: wait = <sec>' (uzun işlemlerde), 'If-Match'/' ETag' (iyimser kilitler).
Geçerli 'Retry-After'ile 425/429/503 önemli bir çakışma için 409.
"Uzun" işlemler için - asenkron durumun alınması (durum kaynağı başına '202 Kabul Edildi' + 'Konum').

13) Test ve kaos senaryoları

Negatif testler: çift gönderme, başka bir gövdeyle tekrarlama, saat uyumsuzluğu.
Sıra dışı: 't2', 't1'den önce gelir.
Zaman aşımı enjeksiyonu/' RST'/' EOF ', yarım istekler (yavaş POST).
Düşen idempotency depolama - başarısızlık-kapalı davranış (çift yazma-off daha iyi başarısızlık).

14) Metrikler ve uyarılar

'retries _ total {reason}', 'retry _ budget _ used {route}', 'backoff _ seconds _ bucket'.
'idempo _ replay _ total', 'idempo _ conflict _ total', 'duplicate _ detected _ total'.
Rotalara göre 409/425/429/5xx paylaşın; p95/p99 geri çekilmelerle "başarı zamanı".
Uyarılar: yakma oranı bütçeyi yeniden ödeme, idempotence çatışmalarında artış, DLQ büyümesi.

15) Antipatterns

Bir satırda tüm hataları geri çekin.
Jitter eksikliği - retraces senkron dalgaları.
TTL ve temizlik olmadan uzun ömürlü anahtarlar.
Bir yan etki işlendikten sonra sonucun kaydedilmesi (giden kutusu ihlali).
'Trace _ id'/' idempotency _ key' olmayan günlüklerin oluşturulması imkansızdır.
Yazma işlemlerinde agresif paralel retrays.

16) Prod Hazırlık Kontrol Listesi

  • Birleşik politika: ne retrayim, ne değil; Kodlar ve müşteri istemleri.
  • Üstel geri dönüş + tam jitter; 'retry _ budget' belirtilmiş.
  • Sözleşme 'Idempotency-Key' + TTL ile sonuçları depolamak.
  • Olaylar için giden kutusu/gelen kutusu; DLQ; rekabet sınırları.
  • Devre kesici ile entegrasyon, saygı 'Retry-After'.
  • Retray/Duplicate/Conflict tarafından Metrikler/Uyarılar.
  • Bir dizi kaos testi ve ağ hatası öykünmesi.
  • Müşteri belgeleri - yedekleme ve durum örnekleri.

17) TL; DR

Geri çekilmeler sadece idempotency ile birlikte yararlıdır. 'Idempotency-Key' girin ve depolama sonucu, jitter ve retry-budget ile üstel geri dönüş uygulayın, 'Retry-After' saygı, devre kesici ile entegre. Olaylar için - giden kutusu/gelen kutusu; Ödemeler, sıkı veri tekilleştirme ve kilitler için. Geri çekilmeleri ve çakışmaları ölçün, kopyaları ve zaman aşımlarını test edin.

Contact

Bizimle iletişime geçin

Her türlü soru veya destek için bize ulaşın.Size yardımcı olmaya her zaman hazırız!

Telegram
@Gamble_GC
Entegrasyona başla

Email — zorunlu. Telegram veya WhatsApp — isteğe bağlı.

Adınız zorunlu değil
Email zorunlu değil
Konu zorunlu değil
Mesaj zorunlu değil
Telegram zorunlu değil
@
Telegram belirtirseniz, Email’e ek olarak oradan da yanıt veririz.
WhatsApp zorunlu değil
Format: +ülke kodu ve numara (örneğin, +90XXXXXXXXX).

Butona tıklayarak veri işlemenize onay vermiş olursunuz.