استراتژی تکرار و idemotency
1) چرا شما به آن نیاز دارید
در شبکه ها، خرابی ها هنجار هستند: زمان بندی، خطاهای گذرا، خطاهای شبکه، اضافه بار. Retreats بهبود قابلیت اطمینان تنها اگر:1. تکرار امن (idempotent)،
2. تاخیر بین تکرارها مشاهده می شود
3. محدودیت ها/سهمیه ها و اعتیاد «سلامت» احترام می گذارند.
هدف این است که به طور موثر یک بار رفتار در سطح عملیات کسب و کار بدون طول می کشد و نژادها نادرست است.
2) طبقه بندی معانی تحویل
در بیشتر موارد: بدون تکرار، خطر از دست دادن (ورود به سیستم، آتش سوزی و فراموش کردن).
حداقل یک بار: تکراری امکان پذیر است → idempotence مصرف کننده مورد نیاز است (اکثر صف ها، webhooks).
به طور موثر یک بار: تکراری امکان پذیر است، اما به درستی deduplicated (کلید، معاملات، صندوق پستی).
3) هنگامی که به عقب نشینی و زمانی که نه
عقب نشینی منطقی است: «408»، «429» (مشاهده «Retry-After»)، «425» (خیلی زود)، «499» (مشتری بسته شده در محیط)، «5xx»، «504»، وقفه های شبکه/استراحت، «502» در دروازه، «تنظیم مجدد اتصال».
بدون تغییر پرس و جو رد نکنید: «400/ 401/403/404/422».
موارد بحث برانگیز: '409 تعارض (معمولا retrayim ؛ ابتدا وضعیت عملیات را می خوانیم/قصد را دوباره تأیید می کنیم).
4) وقفه، عقب نشینی و لرزش
4. 1 قوانین
اولین timeout، سپس retro: هر درخواست باید یک «مهلت» داشته باشد.
عقب نشینی نمایی: 'delay _ n = base 2 ^ n'، limit 'max _ delay'.
Jitter مورد نیاز است: اضافه کردن تصادفی برای جدا کردن «امواج همزمان کسل کننده».
4. 2 الگوهای لرزش
لرزش کامل: 'sleep = rand (0, base2 ^ n)' بهترین انتخاب کلی است.
jitter تزئین شده: 'sleep = min (max_delay, rand (base, sleep_prev3))' - برای دیالوگ های طولانی.
jitter برابر: 'sleep = base2 ^ n/2 + rand (0, base2 ^ n/2)' - تنوع نرم.
4. 3 بودجه مجدد
نسبت رتریها را محدود کنید:- 'retry _ budget _ per _ min = max (α success_rps، β کف)'; معمولا "α = 0. 1–0. 2`.
- اگر بودجه خسته است، سوئیچ به شکست سریع/قطع کننده مدار «باز».
5) تعامل با محدود کردن سرعت و قطع کننده مدار
به «Retry-After»، «RateLimit-Reset» احترام بگذارید و آن را در قسمت برگشت حساب کنید.
در بالا '5xx '/timeouts - کاهش فرکانس retray و همزمانی کلی.
- نیمه باز: امکان نمونه برداری محدود را فراهم می کند.
- باز: فورا رد (موجب صرفه جویی در منابع).
- بسته: کار معمولی
- در عملیات نوشتن، بهتر است به بازگشت 409/503 با یک اشاره روشن از پیچ و تاب retrays تهاجمی.
6) عدم توانایی عملیات نوشتن
6. 1 ایده عمومی
همان اهداف، یک نتیجه. اساس کلید idempotence و ذخیره سازی سوابق اعدام است.
6. 2 قرارداد HTTP
مشتری هدر را ارسال می کند:
Idempotency-Key: 7a6b7f9e-2a46-4d0b-9c3a-2b30e1c3c9e3
Idempotency-Key-Expiry: 24h # optional
سرور:
- موجب صرفه جویی (کلید، نتیجه → وضعیت، هش بدن) در اولین موفقیت
- اگر تکرار شود، پاسخ قدیمی و هدر 'Idempotency-Replay: true' را باز می گرداند ؛
- در صورت تعارض بدن (همان کلید، اما بار متفاوت) - '409 تعارض'.
6. 3 ذخیره سازی و TTL
کلید جدول/مقدار: «idempotency _ key»، «request _ hash»، «result»، «status»، «expiry _ at».
TTL = پنجره تکرارهای احتمالی و تحویل دیر (معمولا 24-72 ساعت برای پرداخت).
شاخصها با 'idempotency _ key'; برای بار زیاد - هش شاردینگ.
6. 4 مثال طرح (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 شبه کد دستگیره
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) الگوهای «یکبار مصرف»
Transactional Outbox: ضبط یک رویداد تجاری و ارسال یک پیام از همان معامله پایگاه داده از طریق رله پس زمینه ؛ مصرف کننده بی نظیر است.
Inbox/Processed-table at the consumer: ذخیره 'event _ id' برای نادیده گرفتن تکراری.
دقیقا یک بار در کافکا دقیقا یک بار در کسب و کار ≠: حتی با EOS تولید کننده/مصرف کننده، منطق کاربردی هنوز هم باید بی نظیر باشد.
معاملات جبران (Saga): اگر مراحل عقب نشینی و ایجاد عوارض جانبی، ما سیستم را به ناوردا بازگشت.
8) موارد خاص: پرداخت و معاملات مالی
idempointency قوی: کلید به منطق عملیات محدود (به عنوان مثال،. 'external _ payment _ id').
Deduplication در PSP - فروشگاه 'merchant _ reference' → اگر تکرار شود، PSP همان نتیجه را برمی گرداند.
Retrays «from the client»: اجازه می دهد تنها زمانی که «Idempotency-کلید», در غیر این صورت خطر دو نوشتن کردن.
رقابت: قفل «در حساب/ابزار/قرارداد» برای مدت زمان اعدام ؛ هنگامی که تکرار شد، بازگشت 409/423.
قابلیت مشاهده: معیارهای 'idempo _ replay _ total'، 'idempo _ conflict _ total'.
9) Webhooks و چالش های خارجی
امضای HMAC و پنجره زمان ؛ اول تأیید، سپس پردازش.
فرستنده retrays: بازگشت نمایی + jitter, 'max _ تلاش' و DLQ.
مصرف کننده - idempoint: 'event _ id' → جدول/حافظه پنهان ؛ نظم «منظم» تضمین شده نیست.
کدهای: 2xx = موفقیت آمیز، 4xx = تکرار نکنید، 5xx/timeout = تکرار.
10) صف و وظایف پس زمینه
حداقل یک بار به طور پیش فرض → تکراری اجتناب ناپذیر است.
ذخیره «task _ id »/« event _ id» و وضعیت اجرا ؛ با تکراری - مسیر کوتاه «پخش».
DLQ و پیام های سمی: تلاش برای مقابله، قرنطینه، تجزیه دستی.
محدودیت های رقابتی (سمافور) و کارگران بی نظیر.
11) نسخه و «طبیعی» کلید
کلیدهای طبیعی (شماره حساب + تاریخ + شماره سند) مقاومت در برابر تکرار را افزایش می دهند.
هنگام تغییر schema/version، کلید نسخه را در 'Idempotency-Key' یا در هش پرس و جو قرار دهید.
12) هدر های HTTP و پیشنهادات به مشتری
'Idempotency-Key'، 'Idempotency-Replay'، 'Retry-After'، 'Prefer: Wait = <sec>' (در عملیات طولانی)، 'If-Match '/' ETag' (قفل خوش بینانه).
409 برای یک 425/429/503 درگیری کلیدی با «Retry-After» معتبر.
برای عملیات «طولانی» - دریافت وضعیت ناهمزمان ('202 پذیرفته شده' + 'محل سکونت' در هر منبع وضعیت).
13) سناریوهای تست و هرج و مرج
تست های منفی: ارسال دو برابر، تکرار با بدن دیگر، desynchronization ساعت.
خارج از ترتیب: «t2» قبل از «t1» می آید.
تزریق زمان بندی/« RST »/« EOF »، نیمه درخواست (پست آهسته).
Fallen idempotency storage → fail-closed behavior (خرابی بهتر از دوبار نوشتن).
14) معیارها و هشدارها
'retries _ total {reason}', 'retry _ budget _ used {route}', 'backoff _ seconds _ bucket'.
'idempo _ replay _ total', 'idempo _ conflict _ total', 'duplicate _ detected _ total'.
به اشتراک بگذارید 409/425/429/5xx توسط مسیرهای ؛ p95/p99 «زمان موفقیت» با عقب نشینی.
هشدارها: بودجه بازپرداخت نرخ سوختگی، افزایش درگیری های idempotence، رشد DLQ.
15) ضد گلوله
تمام اشتباهات را در یک ردیف جمع کنید.
عدم لرزش → امواج همزمان از retraces.
کلیدهای طولانی مدت بدون TTL و تمیز کردن.
صرفه جویی در نتیجه پس از یک عارضه جانبی (نقض صندوق پستی).
سیاهههای مربوط بدون «trace _ id »/« idempotency _ key» → تولید غیرممکن است.
Retrays موازی تهاجمی در عملیات نوشتن.
16) تولید لیست آمادگی
- سیاست متحد: چه retrayim، چه چیزی نیست ؛ کدها و پیشنهادات مشتری
- عقب نشینی نمایشی + لرزش کامل ؛ بودجه مشخص شده است.
- قرارداد 'Idempotency-Key' + ذخیره نتایج با TTL.
- صندوق پستی/صندوق پستی برای رویدادها ؛ DLQ ؛ محدودیت های رقابتی
- ادغام با قطع کننده مدار، احترام 'Retry-After'.
- معیارها/هشدارها توسط Retray/تکراری/درگیری.
- مجموعه ای از آزمون های هرج و مرج و تقلید شکست شبکه.
- مستندات مشتری - نمونه هایی از پشتیبان گیری و وضعیت.
17) TL ؛ دکتر متخصص
عقب نشینی تنها با idemotency مفید است. «Idempotency-Key» و ذخیره سازی نتیجه را وارد کنید، با استفاده از لرزش و بودجه مجدد، عقب نشینی نمایی را اعمال کنید، به «Retry-After» احترام بگذارید، با قطع کننده مدار ادغام شوید. برای رویدادها - صندوق خروجی/صندوق ورودی ؛ برای پرداخت، deduplication دقیق و قفل. اندازه گیری retrays و درگیری، تکراری آزمون و وقفه.