الويب والتطوير / CLEARBYTE

خطأ HTTP 429: فهم Retry-After وتنظيم إعادة المحاولة

تعني استجابة HTTP 429 أن الخادم يحدّ معدل طلبات العميل. اقرأ تفاصيل الاستجابة و Retry-After ، وخفّض المعدل المشترك، ولا تكرر إلا العمليات الآمنة للتكرار. يجب أن تكون لكل مهمة مهلة نهائية وحد أقصى للمحاولات.

في هذا الدليل

قد يعمل التكامل عند اختباره يدوياً ثم يتعطل عند تشغيل دفعة كبيرة. لكل عامل نشاط يبدو محدوداً، لكن مجموع العمال قد يتجاوز حصة الحساب. استجابة 429 إشارة إلى ضغط العمل كله، وليست أمراً بأن يرسل كل عامل طلبه مجدداً فوراً.

يوضح هذا الدليل سجلاً للتشخيص وحساباً لتنظيم الطابور وطريقة لحساب الانتظار. الأرقام تخص خدمة افتراضية ذات حد موثق، ولا تمثل حدود أي API بعينه. ارجع دائماً إلى عقد الخدمة التي أرسلت الخطأ قبل اختيار العلاج.

حدّد أولاً الجهة التي أرسلت 429

سجّل وقت الطلب والمسار والطريقة والحالة ومعرّف الطلب وترويسات إعادة المحاولة. استبعد بيانات التفويض والبيانات الشخصية من السجل. تحقّق هل الرد صادر عن API المقصود أم وكيلك العكسي أم قاعدة CDN ؛ شكل صفحة الخطأ وحده لا يكشف السياسة المطبقة.

قد يطبق الحد على عنوان IP أو مستخدم موثّق أو تطبيق أو مورد. افحص جسم الرد ولوحة مزود الخدمة. حصة الدقيقة وحد التزامن والحصة اليومية مشكلات مختلفة؛ إبطاء الطابور لن يعيد حصة يومية استُنفدت بالفعل.

  • هل زادت المهام الفعلية أم أن مهمة واحدة بدأت تكرر طلباتها؟
  • هل تتشارك خدمات أو علامات تبويب أو مفاتيح API الحصة نفسها للحساب؟
  • هل يُقاس الحد بعدد الطلبات أم الطلبات النشطة أم الرموز أم مورد آخر؟
  • هل وقت التعافي الموثق يقع داخل المهلة المتاحة لهذا الإجراء؟

اقرأ Retry-After بوحدته الصحيحة

تقبل Retry-After عدداً صحيحاً غير سالب بالثواني أو تاريخ HTTP. القيمة 12 تعني الانتظار اثنتي عشرة ثانية بعد الاستلام، لا اثنتي عشرة مللي ثانية. عند وجود تاريخ، احسب المدة المتبقية بساعة موثوقة؛ انتهاء التاريخ لا يبرر حلقة طلبات متلاحقة.

إذا كانت المهمة تستطيع الانتظار، اعتبر تأخير الخادم الصحيح حداً أدنى، ثم وزع عودة العمال عشوائياً قليلاً. إذا تجاوز التأخير المهلة المتبقية، أوقف المهمة أو أعد جدولتها. لا تختصر توجيه الخادم سراً إلى حد محلي فتواصل الاتصال مبكراً.

قرارات نموذجية بعد استجابة 429
الملاحظة في الردالتفسيرقرار هذه المهمة
Retry-After: 12التأخير 12 ثانيةانتظر 12 ثانية على الأقل إذا سمحت المهلة
Retry-After: تاريخ HTTPيتحدد التأخير بوقت الاستلام ودقة الساعةاحسب مدة غير سالبة وافحص الموعد النهائي
الترويسة غائبة أو غير صالحةلم تُقدَّم مدة انتظار قابلة للاستخدامطبّق سياسة المزود أو تراجعاً محلياً محدوداً
المزود يعلن نفاد الحصة اليوميةالمحاولات القصيرة لا تستعيد الحصةتوقف حتى تتاح الحصة من جديد

احسب ميزانية الطابور المشترك

افترض أن الحساب كله مسموح له بـ 120 طلباً في الدقيقة، وأن المهمة تحتاج 600 طلب. العدد وحده يحتاج خمس دقائق من الحصة إذا لم يوجد نشاط آخر. إرسال 600 طلب خلال عشر ثوان ثم الانتظار لا يلغي الاندفاع؛ قد يرفضه المزود رغم أن متوسط الدقيقة يبدو مناسباً.

نختار في المثال 90 طلباً في الدقيقة لترك مساحة للعمل الآخر. المعدل 1.5 طلب في الثانية، والفاصل الاسمي نحو 667 مللي ثانية. تحتاج 600 طلب إلى نحو 400 ثانية قبل احتساب زمن الردود والإعادات. هذه خطة حسابية وليست ضماناً لتطابقها مع نافذة الحد عند كل مزود.

عندما يستغرق الرد ثانيتين في المتوسط، يشير قانون ليتل إلى تزامن متوسط 1.5 × 2 = 3 في حمل مستقر. استخدم حاجز تزامن للطلبات النشطة ومحدد معدل مشترك لتوقيت البدء؛ أحدهما لا يغني عن الآخر. احسب الإعادات ضمن الميزانية نفسها.

Example workload assumptions:
Account allowance: 120 requests/minute
Operating target: 90 requests/minute = 1.5 requests/second
600 requests / 1.5 requests/second = 400 seconds
Average concurrency at 2 seconds/response: 1.5 × 2 = 3

استخدم تراجعاً محدوداً مع توزيع عشوائي

عندما لا يقدم الخادم مدة صالحة، وسّع نافذة الانتظار بعد الإخفاقات المتكررة ووزّع الانتظار داخلها عشوائياً. يمكن أن تكون النوافذ ثانية وثانيتين وأربعاً وثمانياً، مع مهلة إجمالية مستقلة. يمنع ذلك عودة جميع العمال في اللحظة نفسها.

تحسب الدالة أدناه التأخير فقط، ولا تنفذ عميلاً كاملاً. على المستدعي ضبط المهلة وحد المحاولات والإلغاء وأمان تكرار العملية. وقد يحتاج المتصفح إلى أن يكشف الخادم ترويسة Retry-After عبر CORS قبل أن تستطيع JavaScript قراءتها.

function retryDelayMs(retryAfter, attempt, nowMs = Date.now()) {
  const text = String(retryAfter ?? "").trim();
  if (/^\d+$/.test(text)) {
    const milliseconds = Number(text) * 1000;
    return Number.isSafeInteger(milliseconds) ? milliseconds : Infinity;
  }
  if (/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), \d{2} (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d{4} \d{2}:\d{2}:\d{2} GMT$/.test(text)) {
    const dateMs = Date.parse(text);
    if (Number.isFinite(dateMs)) return Math.max(0, dateMs - nowMs);
  }
  const windowMs = Math.min(8000, 1000 * 2 ** attempt);
  return Math.floor(Math.random() * windowMs);
}
// Example policy: at most 4 retries and a 30-second total deadline.
// If the required wait exceeds the remaining deadline, stop.

كرّر فقط العملية التي يكون تكرارها آمناً

قراءة مورد تختلف عن إنشاء دفعة مالية. قبل إعادة كتابة، افحص عقد منع التكرار وهل يمكن أن تكون المحاولة السابقة قد نفذت. أعد استخدام مفتاح منع التكرار الموثق للعملية المنطقية نفسها؛ إنشاء مفتاح جديد كل مرة قد ينشئ عمليات منفصلة.

قد يعيد SDK الطلب داخلياً بالفعل. تغليفه بحلقة إضافية يضاعف الضغط بدلاً من علاجه. دوّن أقصى عدد لمحاولات الشبكة عبر الطبقات كلها. في واجهة المستخدم اعرض حالة واضحة للمحاولة لاحقاً بدلاً من إبقاء زر يدور أثناء طابور طويل خفي.

  • ضع مهلة إجمالية واحدة، ومرّر الإلغاء إلى العمل المنتظر.
  • اضبط التزامن ومعدل البدء على مستوى الحصة المشتركة.
  • حرر موارد الرد المكتمل قبل الانتظار أو التكرار.
  • توقف عند نفاد الحصة أو عند خطأ يصفه المزود بأنه دائم.
  • سجّل المحاولات والنتائج النهائية حتى تظهر الإعادات في المراقبة.

تحقّق بدفعة صغيرة يمكن حسابها

ابدأ بمجموعة قراءات صغيرة معروفة، وسجّل الطلبات الأصلية والإعادات والنجاحات والإخفاقات النهائية. قارن الفواصل المرصودة وعدد الطلبات النشطة بالخطة. اختبر 429 مصطنعاً بمدة Retry-After معروفة بدلاً من الضغط المتكرر على الخدمة الحية.

يساعد حاسبا معدل الطلبات والتزامن على تحويل الوحدات وفحص فرضية زمن الاستجابة. قارن حسابك بحدود المزود الفعلية. إذا استمرت 429 فافحص مصادر الطلبات المشتركة ونوع الحصة قبل زيادة الانتظار عشوائياً؛ التأخير لا يصلح دائماً الخطأ الأساسي.

أسئلة شائعة

هل تعني 429 أن عنوان IP محظور؟

ليس بالضرورة؛ إنها استجابة لتحديد المعدل. قد تتعلق السياسة بحساب أو رمز أو مسار أو عنوان IP أو الخدمة كلها. اقرأ التفاصيل والوثائق قبل اختيار الحل.

هل أعيد الطلب فوراً إذا غابت Retry-After ؟

غياب الترويسة لا يفرض محاولة فورية. استخدم سياسة المزود أو تراجعاً محدوداً موزعاً عشوائياً، مع حد مشترك للمحاولات.

هل تحل زيادة العمال مشكلة كثرة الطلبات؟

قد تزيد الضغط على الحصة المشتركة. حدّد البعد المحدود أولاً، ثم نسق الطابور والتزامن. تفيد الزيادة فقط إذا كان عقد المزود يسمح بها.

المصادر والتعريفات

تم التحقق من الطريقة: