الخطأ 429 يعني أن حدًّا قد بُلِغ. والسؤال المفيد: حدُّ مَن؟ خادم الويب عندك، أم وسيط أو شبكة توزيع في المقدّمة، أم واجهة برمجية تناديها، أم التطبيق نفسه. لكلٍّ حلٌّ مختلف، وترويسات الردّ تقول غالبًا أيُّها.

اقرأ الردّ أوّلًا

curl -sSI https://yourdomain.com/api/thing | grep -i -E 'retry-after|ratelimit|x-'

ترويسة Retry-After تقول لك كم تنتظر. وترويسات RateLimit تقول السقف وما بقي منه. أمّا 429 بلا هذه الترويسات فهو غالبًا خادمك أنت، أو وسيط لم يُضبَط ليشرح نفسه.

إن كان Nginx عندك

grep "limiting requests" /var/log/nginx/error.log | tail
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;

location /api/ {
    limit_req zone=api burst=20 nodelay;
    limit_req_status 429;
}
خلف شبكة توزيع أو موزّع حِمل، تكون ‎$binary_remote_addr‎ هي الوسيط، فيتشارك كل الزوّار سلّةً واحدة ويكفي حفنةٌ منهم لإسقاط الحدّ على الجميع. اضبط عنوان العميل الحقيقيّ أوّلًا — انظر Cloudflare وعنوان الزائر الحقيقيّ.

وإن كنت أنت المحدود

  • احترم Retry-After. فإعادة المحاولة فورًا تمدّد أغلب الحظر.
  • وتراجع تراجعًا أسّيًّا مع تشويش عشوائيّ، كي لا يعيد أسطولٌ من العمّال المحاولة في صفٍّ واحد.
  • وخبّئ ما تجلبه. فأغلب حدود المعدّل تُبلَغ بتكرار السؤال نفسه.
  • واجمع الطلبات حيث تدعم الواجهة ذلك — نداءٌ واحد لخمسين سجلًّا بدل خمسين نداءً.
for i in 1 2 3 4 5; do
  curl -fsS "$URL" && break
  sleep $(( (2 ** i) + RANDOM % 3 ))
done

وإن كان مسار تسجيل دخول

فهو يعمل كما ينبغي. انظر تحديد معدّل مسار تسجيل الدخول.