خطای 429 Too Many Requests یکی از کدهای وضعیت HTTP است که وقتی رخ می‌دهد، معمولاً کاربران را به‌دلیل مبهم بودن پیام سردرگم می‌کند و توسعه‌دهنده‌ها را در جست‌وجوی یک ریشه مشخص، به لایه اشتباه می‌فرستد. برخلاف 404 که به‌معنای نبود منبع است یا 401 که به‌معنای نبود احراز هویت، این کد یک پیام دقیق از سرور به کلاینت دارد: «تعداد درخواست‌های تو در بازه زمانی مشخص، از حد مجاز فراتر رفته است». این پیام سه نکته مهم دارد: منبع وجود دارد، احراز هویت مسئله نیست، و مشکل در نرخ درخواست است. تفاوت دقیق این کد با کدهای همسایه، نقش هدر Retry-After و RateLimit-*، و روش عیب‌یابی در هر لایه، موضوع اصلی این مقاله است.

429 Too Many Requests دقیقاً چه معنایی دارد؟

در استاندارد HTTP Status Codes، کد 429 در دسته 4xx (خطای کلاینت) قرار می‌گیرد و به‌طور رسمی به این معناست: «کلاینت در بازه زمانی مشخص، تعداد درخواست‌های بیش از حد مجاز ارسال کرده است». این کد در RFC 6585 معرفی شد و به سرورها این امکان را داد که به‌جای بلاک کردن دائمی کاربر یا تحمل اضافه‌بار، با یک پیام شفاف، کلاینت را به کاهش سرعت درخواست‌ها هدایت کنند.

نکته‌ای که اکثر توسعه‌دهنده‌ها به آن توجه نمی‌کنند این است که کد 429 یک «پیام همکاری» است، نه یک خطای مهلک. سرور با فرستادن این کد، به کلاینت می‌گوید که سرویس در دسترس است، اما برای حفظ پایداری، باید درخواست‌ها را با فاصله بیشتر بفرستد. به همین دلیل، RFC توصیه می‌کند سرورها هدر Retry-After را همراه این پاسخ بفرستند تا کلاینت بداند چه مدت باید صبر کند. اگر این هدر نباشد، کلاینت نمی‌داند چه زمانی می‌تواند دوباره تلاش کند و ممکن است در چرخه بی‌پایانی از درخواست‌های ردشده بیفتد. اگر با معماری کلی سرور و پروتکل HTTP آشنا نیستید، ابتدا سرور چیست و چگونه کار می‌کند را بخوانید تا تصویر کلی در ذهن شما شکل بگیرد.

429 یک «نه مؤدبانه» است، نه یک «نه نهایی». سرور می‌گوید «دوباره امتحان کن، اما با فاصله بیشتر». اگر این تفاوت را ندانید، ممکن است در عیب‌یابی به لایه‌های اشتباه بروید.

سه لایه‌ای که باید تفکیک شوند

در تجربه من، خطای 429 همیشه در یکی از این سه لایه ریشه دارد. تفکیک لایه پیش از هر اقدام، نیمی از راه را رفته‌اید:

  • لایه وب‌سرور یا اپلیکیشن: Nginx یا Apache، یا خود اپلیکیشن، بر اساس IP، کاربر یا API Key، نرخ درخواست را محدود می‌کند.
  • لایه میان‌راهی: CDN، WAF، API Gateway یا لودبالانسر، سیاست Rate Limiting خودش را اعمال می‌کند.
  • لایه سرویس خارجی: شما در حال مصرف API یک سرویس خارجی هستید و آن سرویس، نرخ درخواست شما را محدود کرده است.

جدول زیر نگاشت سریع سیمپتوم به لایه خطا را نشان می‌دهد:

سیمپتوملایه احتمالیاولین اقدام تشخیصی
429 بعد از تعداد مشخصی درخواست سریعلایه وب‌سرور یا اپلیکیشنبررسی limit_req در Nginx یا افزونه محدودیت
429 فقط برای بعضی IPهالایه میان‌راهی یا WAFبررسی سیاست Rate Limiting در CDN
429 در پاسخ API خارجیلایه سرویس خارجیبررسی مستندات سهمیه API
429 بعد از اسکن یا حملهلایه WAFبررسی لاگ WAF و سیاست‌های خودکار

تفاوت 429 با 403، 401 و 503

یکی از پرتکرارترین اشتباهات در عیب‌یابی، قاطی کردن کدهای 4xx با همدیگر است. تفاوت بین 429 با کدهای همسایه‌اش را در یک نگاه:

کدمعنانکته کلیدی
401 Unauthorizedهویت تأیید نشدهاحراز هویت اول
403 Forbiddenهویت تأیید شده اما مجوز کافی نیستاحراز هویت مجدد بی‌فایده است
429 Too Many Requestsنرخ درخواست از حد فراتر رفتهاحراز هویت و مجوز درست است
503 Service Unavailableسرویس به‌دلیل اضافه‌بار یا نگهداری در دسترس نیستمشکل در سرور است، نه در کلاینت

این تفکیک در عیب‌یابی حیاتی است. اگر سرور 503 برگرداند، مشکل در لایه سرور است: سرویس به‌دلیل اضافه‌بار یا نگهداری پاسخ نمی‌دهد. اگر 429 برگرداند، مشکل در لایه کلاینت است: درخواست‌ها بیش از حد مجاز ارسال شده. تفاوت دقیق 401 و 403 را در تفاوت احراز هویت و مجوزدهی و روش رفع 403 را در رفع خطای 403 Forbidden در سرور آورده‌ام. راهنمای کامل 401 هم در خطای 401 Unauthorized در سرور موجود است.

429 با 503 تفاوت بنیادین دارد: 429 می‌گوید «تو زیادی درخواست فرستادی، من سالمم»، اما 503 می‌گوید «من به‌دلیل اضافه‌بار یا نگهداری نمی‌توانم پاسخ دهم». یکی به رفتار کلاینت اشاره دارد، دیگری به وضعیت سرور.

Rate Limiting چیست و چگونه کار می‌کند؟

Rate Limiting (محدودسازی نرخ) یک مکانیزم کنترلی است که تعیین می‌کند یک کلاینت در بازه زمانی مشخص، چه تعداد درخواست می‌تواند ارسال کند. این مکانیزم در لایه‌های مختلفی پیاده‌سازی می‌شود: از وب‌سرور (Nginx, Apache) تا CDN (Cloudflare, Fastly)، از API Gateway (Kong, AWS API Gateway) تا خود اپلیکیشن (وردپرس، لاراول، جنگو).

سه الگوریتم اصلی Rate Limiting که در پروژه‌ها دیده‌ام:

  1. Fixed Window: شمارش درخواست‌ها در پنجره‌های زمانی ثابت (مثلاً هر دقیقه). ساده اما در مرزها ناعادلانه: اگر یک کلاینت در ثانیه ۵۹ دقیقه اول ۱۰۰ درخواست بفرستد و در ثانیه ۱ دقیقه دوم هم ۱۰۰ درخواست، در یک بازه ۲ ثانیه‌ای ۲۰۰ درخواست ارسال کرده اما هر دو پنجره را جداگانه پاس کرده است.
  2. Sliding Window: شمارش درخواست‌ها در یک پنجره متحرک از زمان حال به عقب. منصفانه‌تر اما پیچیده‌تر.
  3. Token Bucket: یک سبد توکن که با نرخ مشخصی پر می‌شود و هر درخواست یک توکن مصرف می‌کند. این الگوریتم انعطاف بیشتری دارد و اجازه می‌دهد درخواست‌های انفجاری تا حدی پذیرفته شوند.

روش تشخیص: در لاگ‌های وب‌سرور یا CDN، دنبال الگوی شکست بگردید. اگر شکست‌ها در مرزهای دقیقه یا ساعت رخ می‌دهند، احتمالاً الگوریتم Fixed Window است. اگر در پنجره‌های متحرک، Sliding Window. مبانی معماری وب و Rate Limiting برای مهندسان نرم‌افزار در معماری وب چیست و اصول طراحی معماری وب مدرن آمده است.

هدرهای Retry-After و RateLimit-*

سرورها در پاسخ 429، معمولاً چند هدر مشخص ارسال می‌کنند تا به کلاینت بگویند چگونه رفتار کند. سه هدر اصلی:

  1. Retry-After: یک مقدار عددی (ثانیه) یا تاریخ که به کلاینت می‌گوید چه مدت صبر کند تا دوباره تلاش کند. مثال: Retry-After: 60.
  2. RateLimit-Limit: حداکثر تعداد درخواست مجاز در بازه زمانی مشخص.
  3. RateLimit-Remaining: تعداد درخواست‌های باقی‌مانده در بازه فعلی.
  4. RateLimit-Reset: زمان دقیق (ثانیه) تا ریست شدن پنجره.

متأسفانه هدرهای RateLimit-* هنوز به‌طور جهانی استاندارد نشده‌اند و بعضی پیاده‌سازی‌ها از نام‌های متفاوتی استفاده می‌کنند. اما Retry-After استاندارد رسمی است و باید در هر پاسخ 429 ارسال شود. اگر سروری 429 برگرداند اما هدر Retry-After نداشته باشد، پیاده‌سازی شما ناقص است و کلاینت نمی‌داند چه زمانی دوباره تلاش کند.

روش تشخیص: با curl -i https://example.com/api درخواست را بزنید و همه هدرهای پاسخ را ببینید. اگر هدر Retry-After وجود دارد، مقدار آن را بخوانید و در کد کلاینت، صبر به‌موقع را پیاده کنید. اصول طراحی API و رفتار درست با rate limit را در اصول طراحی REST API و بهینه‌سازی عملکرد REST API آورده‌ام.

در پاسخ 429، هدر Retry-After راهنمای رفتار کلاینت است. اگر این هدر را نادیده بگیرید، درخواست‌های تکراری شما باعث بلاک طولانی‌تر می‌شود.

429 در Nginx و limit_req

در Nginx، Rate Limiting با ماژول ngx_http_limit_req_module پیاده‌سازی می‌شود. این ماژول با دو دستور کلیدی کار می‌کند: limit_req_zone که ناحیه مشترک برای ذخیره شمارنده‌ها تعریف می‌کند و limit_req که محدودیت را در بلوک location یا server اعمال می‌کند. اگر تنظیمات تهاجمی باشد، ممکن است کاربران عادی هم 429 بگیرند.

سه سناریوی دقیق در این لایه:

  1. مقدار burst پایین: limit_req پارامتری به‌نام burst دارد که اجازه می‌دهد درخواست‌های انفجاری تا حدی پذیرفته شوند. اگر این مقدار خیلی پایین باشد، کاربری که صفحه‌اش چند فایل CSS و JS دارد، ممکن است 429 بگیرد.
  2. ناحیه بر اساس IP خیلی سخت‌گیرانه: اگر ناحیه بر اساس IP تعریف شده و محدودیت مثلاً ۱۰ درخواست در ثانیه باشد، در شبکه‌های اشتراکی (NAT) همه کاربران یک IP محسوب می‌شوند و ممکن است بی‌دلیل 429 بگیرند.
  3. عدم استثنا برای IPهای مورد اعتماد: اگر IPهای سرور مانیتورینگ، موتور جستجو یا CDN را در لیست سفید نگذارید، ممکن است آن‌ها هم 429 بگیرند.

روش تشخیص: فایل پیکربندی Nginx را باز کنید و برای کلمات limit_req، limit_req_zone و burst جست‌وجو کنید. اگر محدودیت‌ها تهاجمی هستند، مقدار burst را افزایش دهید یا IPهای مورد اعتماد را استثنا کنید. برای عیب‌یابی عمیق‌تر لاگ‌ها، بررسی خطاهای سرور در لاگ‌ها راهنمای دقیقی است. دستورات ضروری مدیریت سرور را هم در دستورات ضروری CLI آورده‌ام.

429 در Apache و mod_ratelimit

در Apache، Rate Limiting از طریق ماژول mod_ratelimit یا افزونه‌های جانبی پیاده‌سازی می‌شود. mod_ratelimit به‌طور پیش‌فرض در Apache 2.4 موجود است اما فقط روی پهنای باند عمل می‌کند، نه روی تعداد درخواست. برای محدودسازی تعداد درخواست، از ماژول‌های جانبی مثل mod_evasive یا mod_security استفاده می‌شود.

سه سناریوی دقیق در این لایه:

  • mod_evasive با آستانه پایین: اگر آستانه DOSPageCount روی ۵ باشد، کاربری که صفحه را سریع رفرش کند، 429 می‌گیرد.
  • mod_security با قواعد پیش‌فرض: بعضی قواعد پیش‌فرض mod_security درخواست‌های پرتکرار را به‌عنوان «حمله Brute Force» علامت می‌زنند و 429 برمی‌گردانند.
  • تداخل با افزونه‌های وردپرس: اگر افزونه‌ای هم روی Apache، Rate Limiting جداگانه اعمال کند، احتمال 429 چند برابر می‌شود.

روش تشخیص: با apachectl -M | grep ratelimit بررسی کنید که ماژول‌های مربوطه فعال هستند یا نه. فایل پیکربندی یا .htaccess را برای کلمات DOSPageCount، DOSSiteCount و SecRule جست‌وجو کنید. مبانی امنیت سرور Apache را در امنیت سرور چه اصولی دارد و روش افزایش امنیت سرور را در افزایش امنیت سرور آورده‌ام.

429 در CDN و WAF

در معماری‌های مدرن، درخواست‌ها ابتدا از CDN و WAF عبور می‌کنند. اگر این لایه‌ها، نرخ درخواست را به‌عنوان «مشکوک» تشخیص دهند، ممکن است 429 برگردانند حتی اگر وب‌سرور اصلی شما سالم باشد. این یکی از شایع‌ترین سناریوهای 429 در پروژه‌های واقعی است، مخصوصاً وقتی که CDN یا WAF به‌طور خودکار، سیاست‌های Rate Limiting تهاجمی اعمال می‌کنند.

سه سناریوی دقیق در این لایه:

  1. Cloudflare با Rate Limiting پیش‌فرض: Cloudflare در برخی پلن‌ها، Rate Limiting پیش‌فرض دارد که درخواست‌های پرتکرار را بلاک می‌کند. اگر محدودیت‌ها با ترافیک واقعی سایت شما متناسب نباشد، کاربران عادی هم 429 می‌گیرند.
  2. WAF با تشخیص حمله: بعضی WAFها، درخواست‌های سریع از یک IP را به‌عنوان «حمله DDoS» تشخیص می‌دهند و 429 برمی‌گردانند. این سناریو در ترافیک‌های واقعی سایت، شایع است.
  3. API Gateway با quota پیش‌فرض: اگر از API Gateway استفاده می‌کنید، ممکن است quota پیش‌فرض آن با نیاز واقعی شما هماهنگ نباشد.

روش تشخیص: با ابزارهای CDN ببینید که آیا درخواست به سرور اصلی رسیده یا نه. اگر درخواست به سرور نرسیده اما 429 گرفته، ریشه در CDN یا WAF است. توضیح معماری CDN و WAF را در CDN چیست و چگونه کار می‌کند و فایروال ابری در مقابل فایروال سنتی آورده‌ام. برای پیکربندی CDN در وردپرس، راه‌اندازی CDN برای وردپرس نقطه شروع مناسبی است.

در معماری چندلایه، اگر سیاست Rate Limiting در همه لایه‌ها هماهنگ نباشد، درخواست‌های عادی کاربران می‌تواند در مرز بین لایه‌ها بلاک شود. یک عدد واحد برای همه لایه‌ها انتخاب کنید.

429 در وردپرس و REST API

در وردپرس، خطای 429 می‌تواند از سه مسیر رخ دهد: از افزونه‌های امنیتی که Rate Limiting اعمال می‌کنند، از هسته REST API که برای بعضی endpointها محدودیت دارد، و از CDN یا WAF بالادستی که درخواست‌های پرتکرار به wp-json را بلاک می‌کند. هرکدام سناریوهای مخصوص به خود را دارند.

سه سناریوی دقیق در وردپرس:

  1. افزونه امنیتی با Rate Limiting روی wp-login: بعضی افزونه‌های امنیتی مثل Wordfence یا Limit Login Attempts، درخواست‌های مکرر به صفحه ورود را محدود می‌کنند. اگر کاربر رمز خود را چند بار اشتباه وارد کند، 429 می‌گیرد حتی بعد از وارد کردن رمز صحیح.
  2. REST API برای مصرف‌کننده‌های خارجی: اگر اپلیکیشن موبایل یا سرویس خارجی شما به REST API وردپرس متصل می‌شود و درخواست‌های مکرر می‌فرستد، ممکن است 429 بگیرد. راه‌حل: درخواست‌ها را با فاصله و در بسته‌های کوچک‌تر ارسال کنید.
  3. حمله Brute Force که به Rate Limiting منجر می‌شود: اگر سایت شما در حال Brute Force روی wp-login باشد، افزونه امنیتی ممکن است Rate Limiting سراسری اعمال کند و کاربران عادی هم تحت تأثیر قرار بگیرند.

روش تشخیص: با curl -i https://yoursite.com/wp-json/wp/v2/posts درخواست را بزنید و هدر Retry-After را ببینید. اگر مقدار آن کم است (چند ده ثانیه)، محدودیت منطقی است. اگر مقدار آن زیاد است، ممکن است سیاست تهاجمی تنظیم شده. راهنمای کامل REST API وردپرس در API در وردپرس و روش استفاده در استفاده از REST API در وردپرس آمده است. امنیت REST API را هم در امن‌سازی لاگین ادمین و جلوگیری از حملات Brute Force آورده‌ام.

429 در مرورگر و رفتار کلاینت

وقتی کاربر در مرورگر 429 می‌بیند، این خطا معمولاً از سه جهت رخ می‌دهد: از صفحه‌ای که خودش به‌سرعت refresh می‌کند، از کدی که در صفحه، درخواست‌های AJAX مکرر می‌فرستد، یا از یک افزونه مرورگر که رفتار تهاجمی دارد. در تجربه من، اکثر 429 در مرورگر از این سه منشأ می‌آید.

سه سناریوی دقیق در این لایه:

  • AJAX مکرر در صفحه: اگر کدی در صفحه، در حلقه‌ای بی‌پایان درخواست AJAX بفرستد یا polling با فاصله کوتاه داشته باشد، سرور با 429 پاسخ می‌دهد.
  • رفرش سریع صفحه: اگر کاربر یا کد، صفحه را به‌سرعت refresh کند، ممکن است 429 بگیرد.
  • افزونه مرورگر: بعضی افزونه‌های مرورگر، درخواست‌های خودکار به سایت می‌فرستند که باعث 429 می‌شود.

روش تشخیص: با curl -i به URL درخواست بزنید. اگر با curl خطا نگرفتید اما در مرورگر 429 دیدید، ریشه در لایه مرورگر است. کنسول مرورگر و تب Network را باز کنید و ببینید کدام درخواست‌ها فرستاده می‌شوند. روش دقیق را در پیدا کردن خطاهای جاوااسکریپت در کنسول مرورگر آورده‌ام.

429 در APIهای خارجی و سرویس‌های ابری

اگر سایت شما به APIهای خارجی متصل است (مثل Google Maps، Stripe، Mailchimp، یا سرویس‌های داخلی)، ممکن است در پاسخ این APIها 429 ببینید. این سناریو معمولاً به‌دلیل فراتر رفتن از سهمیه (Quota) یا نرخ (Rate) مصوب سرویس رخ می‌دهد. این یکی از پرتکرارترین 429 در پروژه‌های واقعی است، چون ادمین‌ها معمولاً از محدودیت‌های API خارجی بی‌خبرند.

سه سناریوی دقیق در این لایه:

  1. فراتر رفتن از سهمیه روزانه: بعضی APIها سهمیه روزانه دارند (مثلاً ۱۰۰۰ درخواست در روز). اگر سایت شما به این سقف نزدیک شود، درخواست‌های جدید 429 می‌گیرند. راه‌حل: کش‌کردن پاسخ‌ها، کاهش تعداد درخواست‌ها یا ارتقای پلن.
  2. انفجار نرخ درخواست: بعضی APIها به‌جای سهمیه کل، نرخ لحظه‌ای را محدود می‌کنند (مثلاً ۱۰ درخواست در ثانیه). اگر کد شما در یک لحظه ۵۰ درخواست بفرستد، ۴۰ تای آن‌ها 429 می‌گیرند. راه‌حل: پیاده‌سازی صف یا throttling.
  3. عدم احترام به Retry-After: اگر کد شما هدر Retry-After را نادیده بگیرد و بلافاصله دوباره تلاش کند، ممکن است بلاک طولانی‌تری بگیرد.

روش تشخیص: لاگ درخواست‌های خروجی را بررسی کنید و ببینید در چه ساعات یا رویدادهایی 429 رخ می‌دهد. اصول اتصال به APIهای خارجی را در اتصال ووکامرس به APIهای خارجی و مبانی REST API را در REST API چیست آورده‌ام.

دلایل شایع بروز 429

بعد از آشنایی با لایه‌ها، فهرست سریع دلایل شایع 429 در پروژه‌های واقعی را مرور کنیم:

  1. اسکریپت با polling سریع: کدی که درخواست‌های AJAX مکرر می‌فرستد یا در حلقه‌ای بی‌پایان به API وصل می‌شود.
  2. حمله DDoS یا Brute Force: حملات خودکار که درخواست‌های پرتکرار می‌فرستند و سیاست Rate Limiting را فعال می‌کنند.
  3. Rate Limiting تهاجمی در وب‌سرور: Nginx یا Apache با محدودیت‌های سخت‌گیرانه که کاربران عادی هم 429 می‌گیرند.
  4. CDN یا WAF با سیاست خودکار: بعضی سرویس‌ها به‌طور خودکار روی ترافیک سایت، Rate Limiting اعمال می‌کنند.
  5. فراتر رفتن از سهمیه API خارجی: زمانی که سایت شما از سقف درخواست سرویس خارجی فراتر می‌رود.
  6. IP مشترک در شبکه NAT: در شبکه‌های اشتراکی، چند کاربر یک IP محسوب می‌شوند و مجموع درخواست‌هایشان از حد فراتر می‌رود.
  7. مشکل در keep-alive یا session: اگر اتصال‌ها درست مدیریت نشوند، ممکن است درخواست‌های تکراری ارسال شود.
  8. افزونه امنیتی با آستانه پایین: افزونه‌هایی که بدون تنظیم دقیق نصب می‌شوند و ترافیک عادی را به‌عنوان حمله تشخیص می‌دهند.
  9. اسکنرهای امنیتی: ابزارهایی که سایت شما را برای آسیب‌پذیری اسکن می‌کنند و Rate Limiting را فعال می‌کنند.
  10. کد کلاینت بدون Backoff: کدی که در پاسخ به 429، بلافاصله دوباره تلاش می‌کند و چرخه بلاک را تشدید می‌کند.

پروتکل عیب‌یابی گام‌به‌گام

حالا ترتیب عملی عیب‌یابی، از سریع‌ترین به دقیق‌ترین:

  1. بازتولید و ثبت دقیق: با curl -i https://example.com/path درخواست را بزنید و همه هدرهای پاسخ را ثبت کنید. اگر هدر Retry-After وجود دارد، مقدار آن را بخوانید.
  2. بررسی هدرهای RateLimit: اگر سرور هدرهای RateLimit-* می‌فرستد، مقدار Limit، Remaining و Reset را ببینید. این‌ها دقیقاً می‌گویند در کدام پنجره هستید.
  3. بررسی لاگ وب‌سرور: در /var/log/nginx/error.log یا /var/log/apache2/error.log، آخرین درخواست‌های ردشده را ببینید.
  4. بررسی پیکربندی وب‌سرور: فایل Nginx یا Apache را برای کلمات limit_req، burst، DOSPageCount جست‌وجو کنید.
  5. بررسی CDN و WAF: اگر از CDN استفاده می‌کنید، لاگ آن را بررسی کنید که آیا درخواست به سرور اصلی رسیده یا بلاک شده.
  6. تست از IP دیگر: اگر از IP دیگری درخواست بزنید، آیا خطا رفع می‌شود؟ اگر بله، ریشه در محدودیت IP است.
  7. بررسی لاگ API خارجی: اگر به API خارجی وصل می‌شوید، لاگ درخواست‌های خروجی را ببینید و مصرف سهمیه را چک کنید.
  8. بررسی افزونه‌های وردپرس: اگر روی وردپرس هستید، افزونه‌های امنیتی و Rate Limiting را موقتاً غیرفعال کنید و تست بگیرید. اگر خطا رفع شد، ریشه در همان افزونه است.
  9. بررسی کد کلاینت: اگر اپلیکیشن موبایل یا سرویس خارجی شما به API وصل می‌شود، کد آن را بررسی کنید که هدر Retry-After را احترام بگذارد.
  10. بررسی ترافیک سایت: اگر ترافیک سایت ناگهان بالا رفته، ممکن است حمله DDoS یا اسکن امنیتی در جریان باشد. لاگ‌ها را برای الگوهای مشکوک بررسی کنید.

برای خطاهای مرتبط با سرور، خطای 500 Internal Server Error، خطای 502 Bad Gateway و خطای 503 Service Unavailable مسیرهای مکمل عیب‌یابی هستند. برای مبانی امنیت وب، امنیت وب چیست راهنمای دقیقی است.

در عیب‌یابی 429، اولین کار این نیست که Rate Limiting را غیرفعال کنم. اولین کار این است که با curl -i بفهمم سرور دقیقاً چه هدرهایی برگردانده و کدام لایه مسئول بلاک است.

اشتباهات پرهزینه در تشخیص

در پرونده‌های پشتیبانی که بازبینی کرده‌ام، این پنج اشتباه بیشتر از بقیه تکرار می‌شود:

  • غیرفعال کردن کورکورانه Rate Limiting: اگر Rate Limiting را برای «رفع سریع» غیرفعال کنید، سایت را در برابر حملات DDoS و Brute Force باز می‌گذارید. راه‌حل: تنظیم دقیق آستانه‌ها، نه غیرفعال کردن.
  • اشتباه گرفتن 429 با 503: 429 از لایه کلاینت می‌آید، 503 از لایه سرور. اگر این دو را قاطی کنید، در لایه اشتباه وقت تلف می‌کنید.
  • نادیده گرفتن هدر Retry-After: اگر این هدر را نادیده بگیرید و بلافاصله دوباره درخواست بفرستید، در چرخه بلاک طولانی‌تری می‌افتید.
  • تنظیم ناهماهنگ در لایه‌ها: اگر CDN و وب‌سرور Rate Limiting متفاوتی داشته باشند، کاربران عادی می‌توانند بی‌دلیل 429 بگیرند. همیشه آستانه‌ها را در همه لایه‌ها هماهنگ کنید.
  • بی‌توجهی به APIهای خارجی: اگر سایت شما به API خارجی وصل است، قبل از عیب‌یابی لایه‌های داخلی، مصرف سهمیه API خارجی را چک کنید.

پرسش‌های پرتکرار درباره خطای 429 Too Many Requests

429 Too Many Requests با 503 Service Unavailable چه تفاوتی دارد؟ 429 به‌معنای «تعداد درخواست‌های تو از حد مجاز فراتر رفته» است و به رفتار کلاینت اشاره دارد. اما 503 به‌معنای «سرور به‌دلیل اضافه‌بار یا نگهداری در دسترس نیست» است و به وضعیت سرور اشاره دارد. در 429، سرور سالم است و فقط نرخ درخواست مسئله است؛ در 503، خود سرور توان پاسخ‌دهی ندارد.

چرا خطای 429 فقط برای بعضی کاربران رخ می‌دهد؟ این نشانه Rate Limiting بر اساس IP است. کاربرانی که از شبکه‌های اشتراکی یا NAT استفاده می‌کنند، یک IP محسوب می‌شوند و مجموع درخواست‌هایشان از حد فراتر می‌رود. با بررسی IP کاربران در لاگ، الگو را می‌بینید.

آیا 429 توسط خود وردپرس برگردانده می‌شود؟ هسته وردپرس به‌طور پیش‌فرض Rate Limiting روی REST API اعمال نمی‌کند (فقط برای بعضی endpointهای خاص محدودیت‌های سبک دارد). ولی افزونه‌های امنیتی، CDN یا WAF می‌توانند در لایه‌های بالاتر، Rate Limiting اعمال کنند و پاسخ 429 بدهند.

چرا بعد از نصب افزونه امنیتی، خطای 429 افزایش یافت؟ افزونه‌های امنیتی معمولاً Rate Limiting تهاجمی روی صفحه ورود و REST API اعمال می‌کنند. اگر آستانه‌ها با ترافیک واقعی سایت شما متناسب نباشد، کاربران عادی هم بلاک می‌شوند. آستانه‌ها را با لاگ‌های واقعی تنظیم کنید.

آیا افزایش محدودیت Rate Limiting بی‌خطر است؟ خیر، افزایش بی‌دلیل محدودیت، سایت را در برابر حملات DDoS و Brute Force آسیب‌پذیر می‌کند. همیشه تعادل بین دسترسی کاربران عادی و حفاظت از سایت را حفظ کنید. برای سایت‌های فروشگاهی، آستانه‌های محافظه‌کارانه‌تر توصیه می‌شود.

چرا APIهای خارجی 429 برمی‌گردانند؟ چون از سهمیه یا نرخ درخواست مصوب فراتر رفته‌اید. هر API خارجی، سقف مشخصی برای تعداد درخواست‌ها دارد. با کش‌کردن پاسخ‌ها، کاهش تعداد درخواست‌ها یا ارتقای پلن، این خطا رفع می‌شود.

چطور بفهمم 429 از کدام لایه است؟ با curl -i درخواست بزنید و هدرهای پاسخ را ببینید. اگر هدر Server نشانه‌های Nginx یا Apache داشت، لایه وب‌سرور است. اگر نشانه‌های CDN داشت، لایه CDN است. اگر هیچ‌کدام، لایه API Gateway یا WAF است.

آیا 429 می‌تواند از سمت دیتابیس رخ دهد؟ خیر، 429 یک کد HTTP است که فقط در لایه وب و انتقال معنا دارد. اگر دیتابیس مشکل داشته باشد، معمولاً خطای 500 یا 504 می‌بینید.

آیا کد کلاینت می‌تواند از 429 خودداری کند؟ بله. سه اصل: (۱) هدر Retry-After را احترام بگذارید؛ (۲) از الگوریتم Exponential Backoff برای تلاش مجدد استفاده کنید؛ (۳) درخواست‌ها را با فاصله و در بسته‌های کوچک‌تر ارسال کنید.

چرا بعد از افزودن CDN، Rate Limiting دو برابر شد؟ اگر هم CDN و هم سرور اصلی، Rate Limiting جداگانه اعمال کنند، کاربران در مرز بین دو لایه ممکن است دو بار بلاک شوند. آستانه‌ها را در همه لایه‌ها هماهنگ کنید یا Rate Limiting را فقط در یک لایه فعال نگه دارید.

آیا برای سایت‌های کوچک، Rate Limiting لازم است؟ بله، حتی سایت‌های کوچک در معرض حملات Brute Force و DDoS هستند. با این حال، آستانه‌های Rate Limiting باید متناسب با ترافیک واقعی سایت تنظیم شود، نه با پیش‌فرض‌های تهاجمی.

چطور از بروز 429 در آینده پیشگیری کنم؟ سه اصل: (۱) آستانه‌های Rate Limiting را با ترافیک واقعی سایت هماهنگ کنید؛ (۲) هدرهای Retry-After و RateLimit-* را در همه پاسخ‌ها ارسال کنید؛ (۳) در کد کلاینت، Backoff و احترام به Retry-After را پیاده کنید.

آنچه از این مسیر با ما می‌ماند

خطای 429 Too Many Requests در ظاهر یک پیام ساده است؛ در عمل، یک چالش درباره «نرخ» که در یکی از چند لایه ممکن است شکل گرفته باشد. سه اصل که از این مسیر با من می‌ماند و در هر پروژه واقعی اجرا می‌کنم:

  1. اول لایه را تشخیص بده، بعد راه‌حل را انتخاب کن: 429 می‌تواند از وب‌سرور، CDN، WAF، API خارجی یا کد کلاینت بیاید. با curl -i و بررسی هدرها، اولین قدم را دقیق بردارید.
  2. هماهنگی Rate Limiting در همه لایه‌ها: در معماری چندلایه، آستانه‌های Rate Limiting باید هماهنگ باشند. یک عدد واحد برای همه لایه‌ها انتخاب کنید و آن را مستند کنید.
  3. پیاده‌سازی Backoff و احترام به Retry-After در کد کلاینت: اگر کد شما در پاسخ به 429، بلافاصله دوباره تلاش می‌کند، در چرخه بلاک طولانی‌تری می‌افتد. پیاده‌سازی Exponential Backoff و احترام به هدر Retry-After، رفتار صحیح کلاینت است. اصول این رفتار را در بهینه‌سازی عملکرد REST API آورده‌ام.

اگر در پروژه‌ای با مشکل 429 دست‌وپنجه نرم کرده‌اید، برای من جالب است بدانم کدام لایه بیشترین وقت شما را گرفت: پیکربندی Nginx، CDN، WAF، سهمیه API خارجی یا کد کلاینت. تجربه‌تان را در دیدگاه‌ها بنویسید؛ مخصوصاً اگر نشانه‌ای کشف کرده‌اید که در این فهرست نبوده. همین نشانه‌ها، دقیق‌ترین راهنمای نفر بعدی‌اند. 🚦