خطأ 429 في n8n: الفرق بين Rate Limiting والـ Throttling

حزم بيانات متباعدة تمر عبر بوابة، تعبيرًا عن تنظيم الطلبات لتجنّب خطأ 429 في n8n

بنيت سير عمل (Workflow) في n8n بيكتب أوصاف 300 منتج بالذكاء الاصطناعي ويرفعها على ووكومرس، واشتغل حلو في أول 40 منتج… وبعدين فجأة كله أحمر و429 Too Many Requests. المشكلة مش في الكود، المشكلة إنك بتكلّم الـ API أسرع من اللي مسموح لك بيه.

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

لماذا يظهر خطأ 429 أصلًا؟

كل خدمة خارجية تتعامل معها من n8n، سواء OpenAI أو Google Sheets أو الـ REST API لمتجرك، تضع سقفًا لعدد الطلبات المقبولة منك في فترة زمنية. هذا السقف يحدده المزوّد وحده، وأنت لا تملك تغييره.

ما تملكه هو طريقة استجابة سير العمل: أن تبطّئ الإرسال قبل أن تصل إلى الحد، وأن تتراجع بذكاء إذا وصلت إليه. هذا هو جوهر المقال كله.

Rate Limiting أم Throttling: ماذا سيرى سير العمل؟

المصطلحان يُستخدمان كأنهما شيء واحد، لكن أثرهما على سير العمل مختلف. افترض أن الخدمة تسمح بـ 100 طلب في الدقيقة، وأرسلت الطلب رقم 101 قبل انتهاء الدقيقة.

  • تحديد معدل الطلبات (Rate Limiting): الخدمة ترفض الطلب الزائد، وغالبًا تردّ بالرمز 429. هنا يتوقف سير العمل بخطأ ما لم تجهّز له مسارًا.
  • خنق الطلبات (Throttling): الخدمة تؤخر الطلب أو تضعه في طابور ثم تنفذه لاحقًا. لن ترى خطأ، لكن الاستجابة ستتأخر، وأي خطوة تعتمد عليها ستنتظر.

قبل ما تعيد المحاولة

Rate Limiting مقابل Throttling

ماذا يحدث للطلب رقم 101 إذا كان الحد 100 في الدقيقة؟

المعيارRate LimitingThrottling
مصير الطلب الزائديُرفضيتأخر أو ينتظر
ما يراه سير العملخطأ 429 غالبًااستجابة أبطأ
من يتحكم في الحدمزوّد الخدمةمزوّد الخدمة
ما تفعله أنتتراجع ثم أعد المحاولةزِد مهلة الانتظار
ابن موقعك قطعة قطعةarabcms.com

في الحالتين يبقى القرار عند المزوّد. الفرق أن الأولى تحتاج إعادة محاولة، والثانية تحتاج أن تتحمل الخطوات التالية زمن انتظار أطول (مثلًا مهلة Timeout أكبر في عقدة HTTP Request).

اقرأ حدود الخدمة قبل أن تبني

ليست كل الخدمات تحسب الطلبات بالطريقة نفسها، ونمط الإرسال المناسب لخدمة قد يصطدم بحد خدمة أخرى. هذه أشهر الطرق التي ستقابلها في توثيق أي API:

طريقة الحسابكيف تعملماذا يعني لك
النافذة الثابتة (Fixed Window)عدّاد يُصفَّر مع بداية كل فترة، مثل كل دقيقةقد تمر دفعة كبيرة عند حدود الفترتين، لكن لا تبنِ على ذلك
———
النافذة المنزلقة (Sliding Window)تحسب طلباتك في آخر 60 ثانية بشكل متصلانتظار بداية الدقيقة الجديدة لا يعيد لك الحصة كاملة
دلو الرموز (Token Bucket)رموز تتجمع بمعدل ثابت حتى سعة معينة، وكل طلب يستهلك رمزًايسمح بدفعات قصيرة إذا كنت متوقفًا قبلها
الدلو المثقوب (Leaky Bucket)الطلبات تدخل طابورًا وتخرج بمعدل ثابتالدفعات تُسوّى إلى تدفق منتظم، فلا فائدة من الإرسال دفعة واحدة

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

ماذا تفعل عندما يصلك 429؟

عندما ترفض الخدمة طلبك، انظر أولًا إلى ترويسة Retry-After في الاستجابة. إن وُجدت فهي تخبرك بالمدة التي يجب أن تنتظرها، واحترامها أدق من أي تخمين.

إن لم تجدها، فلا تُعد المحاولة فورًا ولا بفاصل ثابت. استخدم التراجع الأُسّي (Exponential Backoff): انتظر ثانية، ثم ثانيتين، ثم أربعًا، ثم ثماني، مع حد أقصى للانتظار وعدد أقصى للمحاولات حتى لا يدور سير العمل بلا نهاية.

وأضف تشويشًا عشوائيًا (Jitter) على كل مدة. السبب بسيط: إذا فشلت عشرة طلبات معًا وأعادت المحاولة بالتوقيت نفسه، ستصنع موجة ضغط جديدة وتفشل معًا مرة أخرى.

تحذير: لا تُعد المحاولة تلقائيًا على طلب له أثر جانبي قبل أن تتأكد أن الخدمة تدعم عدم تكرار الأثر (Idempotency). إعادة طلب “أنشئ أوردر” أو “اخصم من الرصيد” أو “أرسل رسالة واتساب” قد تنفذه مرتين.

أربع طبقات حماية داخل n8n

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

1. الدفعات داخل عقدة HTTP Request

إذا كانت حدود الخدمة معروفة ومستقرة، فالوقاية أرخص من العلاج. في عقدة HTTP Request، أضف خيار الدفعات (Batching) من قسم Options، واضبط:

  • Items per Batch: عدد العناصر التي تُرسَل في كل دفعة.
  • Batch Interval: مدة الانتظار بين كل دفعة والتي تليها.

احسب القيمتين من حد الخدمة: إذا كان الحد 60 طلبًا في الدقيقة، فدفعة من 10 عناصر كل 10 ثوانٍ تتركك تحت الحد بهامش أمان.

2. حلقة مع عقدة Wait

عندما تحتاج تحكمًا أدق، أو كانت الخطوة ليست HTTP Request مباشرة (عقدة OpenAI مثلًا)، استخدم عقدة Loop Over Items لتقسيم العناصر إلى دفعات، وضع بعد الخطوة عقدة Wait تحدد مدة التوقف قبل الدفعة التالية.

3. Retry On Fail مع انتظار بين المحاولات

التنظيم يقلل 429 لكنه لا يمنعه تمامًا، فقد تشارك حصة الـ API مع سير عمل آخر. من إعدادات العقدة (Settings) فعّل Retry On Fail، وحدد عدد المحاولات وWait Between Tries حتى لا يُعاد الطلب في اللحظة نفسها.

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

4. سير عمل للأخطاء يلتقط ما تبقى

بعض الطلبات ستفشل حتى بعد استنفاد المحاولات. بدل أن تضيع في سجل التنفيذات، أنشئ سير عمل منفصلًا يبدأ بعقدة Error Trigger، واختره من إعدادات سير العمل الأصلي كسير عمل للأخطاء (Error Workflow). من هناك أرسل تنبيهًا على تيليجرام أو بريد، أو سجّل العنصر الفاشل في Google Sheets لتعيد تشغيله لاحقًا.

إعداد جاهز: تراجع أُسّي مع تشويش في عقدة Code

هذه الفكرة تكمّل ما سبق عندما لا يكفيك الفاصل الثابت. اجعل عقدة HTTP Request لا توقف التنفيذ عند الخطأ (اضبط On Error على Continue (using error output))، ومرّر الفرع الفاشل إلى عقدة Code في وضع Run Once for Each Item فيها هذا الكود، ثم إلى عقدة Wait مدتها {{ $json.wait }} ثانية، ثم ارجع إلى الطلب نفسه.

الكود يحسب مدة الانتظار التالية، ويحترم Retry-After إن مرّرته له رقمًا بالثواني:

// n8n Code node — mode: "Run Once for Each Item"
const attempt = $json.attempt ?? 0;            // retries done so far
const maxAttempts = 5;                         // stop after this many
const base = 1;                                // seconds
const cap = 60;                                // never wait longer than this
const retryAfter = Number($json.retryAfter);   // seconds from the Retry-After header, if you passed it

if (attempt >= maxAttempts) {
  return { json: { ...$json, giveUp: true } }; // route this to your error path with an IF node
}

let wait;
if (Number.isFinite(retryAfter) && retryAfter > 0) {
  wait = retryAfter;                           // the provider told us how long to wait
} else {
  const ceiling = Math.min(cap, base * 2 ** attempt);
  wait = Math.random() * ceiling;              // "full jitter"
}

return { json: { ...$json, attempt: attempt + 1, wait: Math.max(1, Math.ceil(wait)) } };

ضع بعد عقدة Code عقدة IF تفحص giveUp: إن كانت true فأرسل العنصر إلى مسار الأخطاء بدل الحلقة.

ملاحظة: بعض الخدمات ترسل Retry-After تاريخًا كاملًا لا عددًا من الثواني. في هذه الحالة سيتجاهله الكود ويرجع إلى التراجع الأُسّي، وهذا سلوك آمن.

بصراحة: هذا القسم مبني على مقال فريق n8n وتوثيقه، لا على تجربة سير عمل عندنا بأرقام حقيقية. القيم 5 محاولات و60 ثانية نقطة بداية معقولة، فعدّلها حسب حدود الخدمة التي تتعامل معها.

أين تقابل هذه المشكلة على موقعك؟

لو كنت فريلانسر تبني أتمتة لعملاء، فهذه أكثر السيناريوهات التي يظهر فيها 429:

  • توليد أوصاف أو ترجمات لمئات المنتجات في ووكومرس عبر OpenAI أو Claude أو Gemini دفعة واحدة.
  • مزامنة الطلبات أو العملاء من ووكومرس إلى Google Sheets أو نظام CRM، خصوصًا عند استيراد البيانات القديمة لأول مرة.
  • نشر مقالات أو تحديث حقول مخصصة بالجملة عبر الـ REST API لووردبريس على استضافة مشتركة تضع حدودها الخاصة.

في ووردبريس: بعض إضافات الأمان والجدران النارية على الاستضافة تحظر عنوان IP الذي يرسل طلبات كثيرة إلى wp-json في وقت قصير. إذا ظهر لك 429 أو 403 من موقعك أنت، فراجع إعدادات إضافة الحماية قبل أن تلوم n8n.

الأسئلة الشائعة

س: ما معنى خطأ 429 Too Many Requests؟
ج: يعني أن الخدمة استقبلت منك طلبات أكثر من الحد المسموح خلال فترة زمنية، فرفضت الطلب الأخير. الحل أن تبطّئ الإرسال أو تنتظر ثم تعيد المحاولة.

س: هل تكفي ميزة Retry On Fail لحل المشكلة؟
ج: تكفي للأخطاء العابرة القليلة. أما إذا كان سير العمل يرسل مئات الطلبات، فابدأ بالدفعات وعقدة Wait، واجعل Retry On Fail شبكة أمان فقط.

س: ما الفرق بين Rate Limiting والـ Throttling باختصار؟
ج: الأول يرفض الطلب الزائد بخطأ، والثاني يؤخره أو يضعه في طابور. الأول يحتاج إعادة محاولة، والثاني يحتاج مهلة انتظار أطول في الخطوات التالية.

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

الخلاصة

خطأ 429 مش عطل، ده الخدمة بتقولك “على مهلك”. نظّم السرعة بالدفعات وعقدة Wait، وخلّي إعادة المحاولة بتراجع أُسّي وتشويش، وفي الآخر سير عمل للأخطاء يلقط اللي فلت.

جرّب تراجع أي سير عمل عندك بيكلّم API بالجملة النهارده، وحط له طبقة واحدة على الأقل من الأربعة دول قبل ما يقع عند العميل.

مراجع إضافية: Handling API rate limits — n8n Docs

مرجع المقال (بالإنجليزية): Throttling vs. Rate Limiting: Backoff Strategies for Workflows
المقال ده مش ترجمة حرفية: متكيّف للقارئ العربي ومضاف عليه سياق ووردبريس وElementor وJetEngine.

اترك تعليقاً