HTTP 429 Too Many Requests: الأسباب والحلول وتحديد المعدل
أنت تقوم بالنشر يوم الجمعة بعد الظهر (أعرف، أعرف)، كل شيء يبدو جيداً، وفجأة يتم تشغيل المراقبة مثل شجرة عيد الميلاد. يتلقى المستخدمون أخطاء 429. واجهة برمجة التطبيقات الخاصة بك ترفض الطلبات. أو ربما يكون الحال معاكساً — أنت تستدعي واجهة برمجة تطبيقات من جهة خارجية وهم يرفضونك. بأي حال، رمز حالة HTTP 429 Too Many Requests أصبح الآن الشيء الأكثر أهمية في يومك.
لقد كنت على جانبي هذا. كنت المطور الذي يرتكب حادثة DDoS عن طريق الخطأ على واجهة برمجة التطبيقات CMS بسبب عملية بناء تم تكوينها بشكل خاطئ، وكنت الشخص الذي ينفذ تحديد المعدل لحماية خوادمنا من العملاء غير المنضبطين. علمتني كلا التجربتين أشياء لا تغطيها المستندات. دعنا نمر بكل ذلك.
جدول المحتويات
- ماذا يعني HTTP 429 فعلاً؟
- الأسباب الشائعة لأخطاء 429
- شرح رأس Retry-After
- كيفية معالجة أخطاء 429 كعميل
- تنفيذ تحديد المعدل في Next.js API Routes
- استراتيجيات تحديد المعدل المقارنة
- تحديد المعدل في Astro والأطر الأخرى
- مراقبة وتصحيح أخطاء 429 في الإنتاج
- الأسئلة الشائعة

ماذا يعني HTTP 429 فعلاً؟
تم تعريف HTTP 429 في RFC 6585، والذي نُشر في عام 2012. المواصفات قصيرة بشكل مفاجئ. ها هي الخلاصة: قام المستخدم (أو العميل) بإرسال طلبات كثيرة جداً في فترة زمنية معينة.
هذا كل شيء. إنها استجابة تحديد المعدل. يقول الخادم، "فهمت طلبك، وهو صحيح على الأرجح، لكنك بحاجة إلى إبطاء السرعة."
هذا يختلف عن 403 Forbidden (أنت غير مسموح لك) أو 503 Service Unavailable (الخادم بأكمله يعاني من الإرهاق). 429 مستهدف. يتعلق الأمر بمعدل الطلب الخاص بك تحديداً.
يجب أن تتضمن الاستجابة رأس Retry-After يخبر العميل بالمدة المراد انتظارها قبل المحاولة مرة أخرى. قلت "يجب" لأن الكثير من واجهات برمجة التطبيقات لا تزعج نفسها، مما يجعل حياة الجميع أصعب.
حيث سترى 429s في العالم الحقيقي
- واجهات برمجة التطبيقات من جهات خارجية: Stripe و OpenAI و GitHub و Contentful و Sanity — كلهم لديهم حدود معدل
- شبكات توصيل المحتوى ومنصات الاستضافة: Vercel و Cloudflare و AWS سترجع 429s إذا اخترقت حدود معدل حوافهم
- واجهات برمجة التطبيقات الخاصة بك: إذا كنت قد نفذت تحديد المعدل (وينبغي عليك أن تفعل)
- عمليات البناء: توليد الموقع الثابت الذي يضرب واجهة برمجة تطبيقات CMS لكل صفحة يمكن بسهولة تشغيل حدود المعدل
- الويب سكراب: إذا كنت تجلب البيانات من مصادر خارجية بقوة
الأسباب الشائعة لأخطاء 429
دعني أقسم السيناريوهات التي واجهتها فعلاً في الإنتاج، مرتبة تقريباً حسب مدى تكرار حدوثها.
1. بناء الموقع الثابت يضرب Headless CMS
هذا هو الذي يعضنا أكثر الفرق التي تعمل مع الهندسات المعمارية بدون رأس. لديك موقع بـ 2000 صفحة، كل منها يحتاج بيانات من CMS الخاص بك. تطلق عملية البناء جميع تلك الطلبات بالتوازي، يرى CMS ارتفاعاً ضخماً، ويبدأ في إرجاع 429s. فشل البناء الخاص بك.
نحن نرى هذا بانتظام عند العمل على مشاريع headless CMS. يتضمن الإصلاح قائمة انتظار الطلبات وحدود التزامن، والتي سأغطيها أدناه.
2. التخزين المؤقت المفقود أو المكسور
إذا أطلق تحميل كل صفحة استدعاء API طازج لأن طبقة التخزين المؤقت الخاصة بك لا تعمل، فسوف تضرب حدود المعدل بسرعة — خاصة مع ارتفاعات المرور. قمت مرة بتصحيح تطبيق Next.js حيث تم تعيين revalidate عن طريق الخطأ إلى 0، مما يعني أن ISR كان معطلاً فعلياً. أطلق كل زائر استدعاء API جديد إلى Contentful. استغرق الأمر حوالي 45 دقيقة من حركة المرور الحقيقية لبدء الحصول على 429s.
3. حلقات إعادة المحاولة بدون Backoff
يحصل الكود على خطأ، ويعاد المحاولة على الفور، ويحصل على خطأ آخر، ويعاد المحاولة على الفور... تهانينا، لقد بنيت آلة تشغيل حد المعدل. رأيت هذا النمط في معالجات webhook والمهام الخلفية وحتى استدعاءات fetch من جانب العميل.
4. خدمات متعددة تشارك مفتاح API
بيئة التطوير المرحلة الخاصة بك، وبيئة الإنتاج الخاصة بك، وإعداد التطوير المحلي الخاص بك، وخط أنابيب CI/CD الخاص بك يستخدمون جميعاً مفتاح API نفسه. يبدو كل واحد منهم جيداً بشكل فردي، لكن بشكل جماعي يحرقون ميزانية حد المعدل الخاصة بك.
5. جلب من جانب العميل بدون Debouncing
ميزة البحث أثناء الكتابة التي تطلق استدعاء API عند كل ضغطة مفتاح. لوحة معلومات التي يتم الاستقصاء كل 500 ميلي ثانية. التمرير اللانهائي الذي يشغل جلسات أسرع من قدرة المستخدم على التمرير. يمكن لهذه الأنماط بالتأكيد تشغيل 429s، خاصة عند ضربها في جميع المستخدمين الخاصين بك.
6. الإساءة الفعلية أو الهجوم
أحياناً يقوم 429 بعمله بالضبط — حماية الخادم الخاص بك من شخص ما يرسل عدداً غير معقول من الطلبات. البوتات والتخمين التصديقي والخردش — تحديد المعدل هو خط دفاعك الأول.
شرح رأس Retry-After
رأس Retry-After هو طريقة الخادم في إخبارك بالضبط متى تحاول مرة أخرى. يمكن أن يأتي بصيغتين:
ثوانٍ للانتظار:
HTTP/1.1 429 Too Many Requests
Retry-After: 60
تاريخ/وقت محدد:
HTTP/1.1 429 Too Many Requests
Retry-After: Thu, 01 Jan 2026 00:00:00 GMT
صيغة الثواني هي الأكثر شيوعاً. صيغة التاريخ تستخدم HTTP-date كما هو محدد في RFC 7231.
إليك ما لن تخبرك به معظم البرامج التعليمية: العديد من واجهات برمجة التطبيقات لا ترسل Retry-After على الإطلاق، أو ترسله بشكل غير متسق. تتضمن واجهة برمجة التطبيقات OpenAI بشكل عام. تتضمن واجهة برمجة تطبيقات GitHub جنباً إلى جنب مع X-RateLimit-Reset. الكثير من واجهات برمجة التطبيقات الأصغر ترسل 429 عارياً وتتركك تخمن.
بعض واجهات برمجة التطبيقات أيضاً ترسل رؤوس حدود معدل إضافية:
| رأس | الهدف | مثال |
|---|---|---|
X-RateLimit-Limit |
الحد الأقصى للطلبات المسموح بها في النافذة | 100 |
X-RateLimit-Remaining |
الطلبات المتبقية في النافذة الحالية | 0 |
X-RateLimit-Reset |
طابع زمني Unix عند إعادة تعيين النافذة | 1735689600 |
Retry-After |
ثوان للانتظار قبل إعادة المحاولة | 30 |
تحقق دائماً من هذه الرؤوس. تتيح لك تنفيذ منطق إعادة محاولة أذكى وحتى إبطاء السرعة بشكل استباقي قبل الوصول إلى الحد الأقصى.

كيفية معالجة أخطاء 429 كعميل
عندما تتلقى أخطاء 429، إليك كيفية التعامل معها بشكل صحيح.
Exponential Backoff مع Jitter
هذا هو المعيار الذهبي. لا تنتظر فقط مقدار زمني ثابتاً — زد التأخير بشكل أسي مع كل إعادة محاولة، وأضف عشوائية (jitter) لمنع مشاكل thundering herd.
async function fetchWithRetry(
url: string,
options: RequestInit = {},
maxRetries: number = 5
): Promise<Response> {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await fetch(url, options);
if (response.status !== 429) {
return response;
}
if (attempt === maxRetries) {
throw new Error(`Still getting 429 after ${maxRetries} retries`);
}
// Check for Retry-After header first
const retryAfter = response.headers.get('Retry-After');
let delay: number;
if (retryAfter) {
// Could be seconds or a date
const parsed = parseInt(retryAfter, 10);
if (!isNaN(parsed)) {
delay = parsed * 1000;
} else {
delay = new Date(retryAfter).getTime() - Date.now();
}
} else {
// Exponential backoff with jitter
const baseDelay = Math.pow(2, attempt) * 1000;
const jitter = Math.random() * 1000;
delay = baseDelay + jitter;
}
console.log(`Rate limited. Waiting ${Math.round(delay / 1000)}s before retry ${attempt + 1}`);
await new Promise(resolve => setTimeout(resolve, delay));
}
// TypeScript wants this, though we'll never reach it
throw new Error('Unexpected end of retry loop');
}
Request Queuing لعمليات البناء
لعمليات توليد الموقع الثابت حيث تحتاج إلى جعل مئات أو آلاف من استدعاءات API، استخدم قائمة انتظار بتحكم التزامن:
import pLimit from 'p-limit';
// Limit to 5 concurrent requests
const limit = pLimit(5);
const pages = await getAllPageSlugs(); // Returns ['/', '/about', '/blog/post-1', ...]
const results = await Promise.all(
pages.map(slug =>
limit(() => fetchWithRetry(`https://api.cms.com/pages/${slug}`))
)
);
مكتبة p-limit (أكثر من 2.5 مليون تنزيل أسبوعي npm في عام 2025) هي ما أختاره لهذا. يمكنك أيضاً إضافة تأخير بين الطلبات:
const limit = pLimit(3);
const delay = (ms: number) => new Promise(r => setTimeout(r, ms));
const results = await Promise.all(
pages.map((slug, i) =>
limit(async () => {
if (i > 0) await delay(200); // 200ms between requests
return fetchWithRetry(`https://api.cms.com/pages/${slug}`);
})
)
);
تنفيذ تحديد المعدل في Next.js API Routes
الآن دعنا ننقلب إلى الجانب الآخر — أنت تبني واجهة برمجة تطبيقات وتحتاج إلى حمايتها. إذا كنت تبني مع Next.js، فإليك كيفية إضافة تحديد المعدل إلى مسارات API الخاصة بك.
محدد معدل بسيط في الذاكرة
للنشر على خادم واحد أو أثناء التطوير، يعمل هذا:
// lib/rate-limit.ts
type RateLimitEntry = {
count: number;
resetTime: number;
};
const rateLimitMap = new Map<string, RateLimitEntry>();
export function rateLimit({
windowMs = 60 * 1000,
maxRequests = 100,
}: {
windowMs?: number;
maxRequests?: number;
} = {}) {
return function check(identifier: string): {
allowed: boolean;
remaining: number;
resetIn: number;
} {
const now = Date.now();
const entry = rateLimitMap.get(identifier);
if (!entry || now > entry.resetTime) {
rateLimitMap.set(identifier, {
count: 1,
resetTime: now + windowMs,
});
return { allowed: true, remaining: maxRequests - 1, resetIn: windowMs };
}
if (entry.count >= maxRequests) {
return {
allowed: false,
remaining: 0,
resetIn: entry.resetTime - now,
};
}
entry.count++;
return {
allowed: true,
remaining: maxRequests - entry.count,
resetIn: entry.resetTime - now,
};
};
}
استخدامه في مسار App Router API في Next.js:
// app/api/data/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { rateLimit } from '@/lib/rate-limit';
const limiter = rateLimit({ windowMs: 60_000, maxRequests: 30 });
export async function GET(request: NextRequest) {
const ip = request.headers.get('x-forwarded-for') ?? 'anonymous';
const { allowed, remaining, resetIn } = limiter(ip);
if (!allowed) {
return NextResponse.json(
{ error: 'Too many requests. Please slow down.' },
{
status: 429,
headers: {
'Retry-After': String(Math.ceil(resetIn / 1000)),
'X-RateLimit-Limit': '30',
'X-RateLimit-Remaining': '0',
},
}
);
}
// Your actual route logic here
return NextResponse.json(
{ data: 'Here you go' },
{
headers: {
'X-RateLimit-Limit': '30',
'X-RateLimit-Remaining': String(remaining),
},
}
);
}
تحديد المعدل في الإنتاج مع Upstash Redis
ينقطع النهج في الذاكرة عندما تعمل على منصات بدون خادم مثل Vercel، لأن كل استدعاء دالة قد يصل إلى مثيل مختلف. أنت بحاجة إلى مخزن مشترك. Upstash Redis هو الخيار الأكثر شيوعاً لهذا في عام 2025.
npm install @upstash/ratelimit @upstash/redis
// lib/rate-limit.ts
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
export const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(30, '60 s'),
analytics: true,
prefix: 'api-ratelimit',
});
// app/api/data/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { ratelimit } from '@/lib/rate-limit';
export async function GET(request: NextRequest) {
const ip = request.headers.get('x-forwarded-for') ?? '127.0.0.1';
const { success, limit, remaining, reset } = await ratelimit.limit(ip);
if (!success) {
const retryAfter = Math.ceil((reset - Date.now()) / 1000);
return NextResponse.json(
{ error: 'Rate limit exceeded' },
{
status: 429,
headers: {
'Retry-After': String(retryAfter),
'X-RateLimit-Limit': String(limit),
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': String(reset),
},
}
);
}
return NextResponse.json({ data: 'Success' }, {
headers: {
'X-RateLimit-Limit': String(limit),
'X-RateLimit-Remaining': String(remaining),
},
});
}
المستوى المجاني من Upstash يمنحك 10000 طلب/يوم، وهو كافٍ للمشاريع الصغيرة. تبدأ خطتهم Pro بـ 10 دولارات/شهر لـ 500K من الأوامر اليومية اعتباراً من أوائل عام 2025.
تحديد المعدل على مستوى Middleware
إذا كنت تريد تحديد المعدل عبر جميع مسارات API الخاصة بك، فإن برنامج Next.js middleware هو المكان:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { ratelimit } from '@/lib/rate-limit';
export async function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/api/')) {
const ip = request.headers.get('x-forwarded-for') ?? '127.0.0.1';
const { success, reset } = await ratelimit.limit(ip);
if (!success) {
return NextResponse.json(
{ error: 'Too many requests' },
{
status: 429,
headers: {
'Retry-After': String(Math.ceil((reset - Date.now()) / 1000)),
},
}
);
}
}
return NextResponse.next();
}
export const config = {
matcher: '/api/:path*',
};
استراتيجيات تحديد المعدل المقارنة
ليست جميع خوارزميات تحديد المعدل متساوية. إليك كيفية مقارنة الخوارزميات الرئيسية:
| خوارزمية | كيف تعمل | المميزات | العيوب | الأفضل لـ |
|---|---|---|---|---|
| Fixed Window | تعد الطلبات في نوافذ زمنية ثابتة (مثل في الدقيقة) | بسيط للتنفيذ | يمكن أن تسمح طفرة حدودية بـ 2x الحد الأقصى | واجهات برمجة التطبيقات البسيطة والأدوات الداخلية |
| Sliding Window | تعد الطلبات خلال فترة زمنية متدحرجة | توزيع أسلس | أكثر تعقيداً قليلاً واستهلاك الذاكرة | معظم واجهات برمجة التطبيقات الإنتاجية |
| Token Bucket | يتم إعادة ملء الرموز بمعدل ثابت، كل طلب يكلف رمز | يسمح بطفرات مراقبة | إدارة الحالة أكثر تعقيداً | واجهات برمجة التطبيقات التي تحتاج إلى تسامح الطفرة |
| Leaky Bucket | تدخل الطلبات إلى قائمة انتظار وتتم معالجتها بمعدل ثابت | معدل إخراج سلس جداً | يمكن إضافة زمن انتظار، قد تُرفض الطلبات | توصيل webhook ومعالجة الوظائف |
| Sliding Window Log | يخزن طابع زمني لكل طلب | دقة عالية جداً | استهلاك ذاكرة عالي في النطاق | احتياجات دقة منخفضة الحجم عالية |
لمعظم تطبيقات الويب، sliding window هو الحل الوسط. هذا ما يستخدمه Upstash بشكل افتراضي، وهذا ما سأوصي به إلا إذا كان لديك سبب محدد لاختيار شيء آخر.
تحديد المعدل في Astro والأطر الأخرى
إذا كنت تبني مع Astro، فإن تحديد المعدل يعمل بشكل مختلف لأن Astro هو إطار موجه للثابت في المقام الأول. لكن مع نقاط نهاية خادم Astro (متاحة في وضع SSR)، المفاهيم متطابقة:
// src/pages/api/data.ts
import type { APIRoute } from 'astro';
import { Ratelimit } from '@upstash/ratelimit';
import { Redis } from '@upstash/redis';
const ratelimit = new Ratelimit({
redis: Redis.fromEnv(),
limiter: Ratelimit.slidingWindow(30, '60 s'),
});
export const GET: APIRoute = async ({ request }) => {
const ip = request.headers.get('x-forwarded-for') ?? '127.0.0.1';
const { success, reset } = await ratelimit.limit(ip);
if (!success) {
return new Response(JSON.stringify({ error: 'Rate limit exceeded' }), {
status: 429,
headers: {
'Content-Type': 'application/json',
'Retry-After': String(Math.ceil((reset - Date.now()) / 1000)),
},
});
}
return new Response(JSON.stringify({ data: 'Hello' }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
};
بالنسبة للتطبيقات المنشورة على الحافة في Cloudflare Workers، قد تفكر أيضاً في استخدام قواعد تحديد المعدل المدمجة في Cloudflare، والتي تعمل على مستوى البنية التحتية ويمكنها التعامل مع حركة أكثر بكثير من الحلول على مستوى التطبيق. يبدأ تحديد معدلهم المتقدم بـ 0.05 دولار لكل 10000 طلب جيد في خطة العمل.
مراقبة وتصحيح أخطاء 429 في الإنتاج
لا يمكنك إصلاح ما لا تستطيع رؤيته. إليك قائمة التحقق الخاصة بي للتعامل مع أخطاء 429 في الإنتاج:
عندما تتلقى 429s
- تحقق من أي واجهة برمجة تطبيقات ترجع 429 — انظر إلى URL الاستجابة وليس فقط رمز الحالة
- سجل رأس
Retry-After— إذا كان طويلاً باستمرار جداً، فقد تحتاج إلى خطة مستوى أعلى - دقق في أنماط الطلب الخاصة بك — هل تقوم بعمل استدعاءات زائدة؟ هل يمكنك دمج الطلبات؟
- تنفيذ التخزين المؤقت — استخدم
stale-while-revalidateأو Redis caching أو Next.js ISR لتقليل استدعاءات API - تحقق مما إذا كانت بيئات متعددة تشارك مفاتيح API — هذا هو السبب الغامض الأكثر شيوعاً لـ 429
عندما تُرسل 429s
- قم بإعداد لوحات معلومات — تتبع معدلات استجابة 429 بمرور الوقت
- حدد أهم المخالفين — أي عناوين IP أو مفاتيح API تضرب الحدود القصوى؟
- راجع حدودك — هل هي مقيدة جداً؟ فضفاض جداً؟ تحقق من سعة الخادم الخاص بك وقم بالتعديل
- أرسل دائماً
Retry-After— كن عميل واجهة برمجة تطبيقات جيد - أرسل رسالة خطأ مفيدة — أخبر العميل بأي حد وصلوا إليه ومتى سيحاولون مرة أخرى
تبدو استجابة 429 المكتوبة جيداً كما يلي:
{
"error": {
"type": "rate_limit_exceeded",
"message": "You've exceeded 30 requests per minute. Please wait before retrying.",
"retryAfter": 42,
"documentation": "https://docs.yourapi.com/rate-limits"
}
}
هذا أفضل بكثير من مجرد { "error": "Too many requests" }.
إذا كنت تتعامل مع مشاكل تحديد معدل مستمرة على هندسة بدون رأس — سواء كان الأمر خلال البناء أو في وقت التشغيل أو كليهما — فقد يكون من الجدير الاتصال بنا لمناقشة هندستك المعمارية. رأينا الكثير من هذه المشاكل عبر مجموعات CMS والإطار المختلفة وعادة ما يكون هناك إصلاح على مستوى النمط بدلاً من مجرد خياطة الأعراض.
الأسئلة الشائعة
ماذا يعني HTTP 429 Too Many Requests؟
HTTP 429 هو رمز حالة يعني أنك أرسلت طلبات كثيرة جداً إلى خادم في فترة زمنية معينة. يقيد الخادم معدلك — يطلب منك أن تبطئ السرعة. إنه ليس خطأ في المصادقة أو خطأ في الخادم؛ طلباتك صحيحة على الأرجح، هناك الكثير منها فقط. يجب أن يتضمن الخادم رأس Retry-After يخبرك متى تحاول مرة أخرى.
كيف يمكنني إصلاح خطأ 429؟
إذا كنت تتلقى أخطاء 429 من واجهة برمجة تطبيقات، قم بتنفيذ exponential backoff مع jitter في منطق إعادة المحاولة الخاص بك، وقلل من تكرار الطلب، وأضف التخزين المؤقت لتجنب الاستدعاءات المكررة، واحترم رأس Retry-After. إذا كنت تصل إلى الحد أثناء البناء، استخدم قائمة انتظار الطلبات بحدود التزامن. إذا كان يحدث باستمرار، فقد تحتاج إلى الترقية إلى خطة API أعلى بحدود معدل أكثر سخاءً.
ما رأس Retry-After؟
رأس Retry-After الذي يتم إرساله مع 429 (أو 503) يخبر العميل بالمدة المراد الانتظار قبل إجراء طلب آخر. يمكن تحديده كعدد من الثواني (مثل Retry-After: 60) أو كتاريخ HTTP (مثل Retry-After: Thu, 01 Jan 2026 00:00:00 GMT). لا تتضمن جميع واجهات برمجة التطبيقات هذا الرأس، لكن الواجهات المصممة جيداً تفعل.
كيف يمكنني تنفيذ تحديد المعدل في Next.js؟
للتطوير أو نشر خادم واحد، يمكنك استخدام Map في الذاكرة لتتبع عدد الطلبات لكل عنوان IP. لنشر الإنتاج بدون خادم على منصات مثل Vercel، استخدم Upstash Redis مع حزمة @upstash/ratelimit. يمكنك تطبيق تحديد المعدل على مستوى المسار الفردي أو عبر جميع مسارات API باستخدام برنامج Next.js middleware.
ما الفرق بين أخطاء 429 و 503؟
429 Too Many Requests متعلق تحديداً بتحديد المعدل — يرسل العميل الخاص بك طلبات كثيرة جداً. يعني 503 Service Unavailable أن الخادم مثقل الأحمال أو تحت الصيانة ولا يمكنه التعامل مع أي طلبات من أي شخص. يمكن لكليهما أن يتضمن رأس Retry-After، لكنهما يشير إلى مشاكل مختلفة جداً. 429 موجه لك؛ 503 يؤثر على الجميع.
هل يمكن لتحديد المعدل منع هجمات DDoS؟ تحديد المعدل هو طبقة واحدة من الدفاع ضد هجمات DDoS، لكنه ليس كافياً بمفرده. يمكن لتحديد المعدل على مستوى التطبيق (مثل ما تنفذه في Next.js) التعامل مع الإساءة المعتدلة، لكن هجوم DDoS الخطير يحتاج إلى التخفيف على مستوى البنية التحتية — باستخدام خدمات مثل Cloudflare أو AWS Shield أو حماية مدمجة لمزود الاستضافة الخاص بك. فكر في تحديد المعدل على مستوى التطبيق كحارس، وحماية على مستوى البنية التحتية كجدران القلعة.
ما حد المعدل الذي يجب أن أعينه لواجهة برمجة تطبيقاتي؟ هذا يعتمد تماماً على حالتك الاستخدام. نقطة البداية الشائعة لواجهات برمجة التطبيقات العامة هي 60 طلب في الدقيقة لكل IP أو 1000 طلب في الساعة لكل مفتاح API. بالنسبة للمستخدمين المصرح لهم، قد تسمح بمزيد. الأهم هو مراقبة أنماط الاستخدام الفعلية، وتعيين الحدود التي تستوعب الاستخدام المشروع مع بعض الهامش، والتعديل بناءً على البيانات الفعلية. ابدأ أكثر تقييداً وتخفيف — من الأسهل تشديد الحدود بعد أن يعتمد المستخدمون على معدلات أعلى.
لماذا أتلقى أخطاء 429 أثناء بناء موقعي الثابت؟
مولدات الموقع الثابتة مثل Next.js و Astro تجلب البيانات لكل صفحة في وقت البناء. إذا كان لديك مئات أو آلاف من الصفحات، فهذه مئات أو آلاف من استدعاءات API في تسلسل سريع. معظم واجهات برمجة تطبيقات CMS لديها حدود معدل بين 5-20 طلب في الثانية. استخدم p-limit أو مكتبات مماثلة لتحديد التزامن بـ 3-5 طلبات متزامنة، وأضف تأخيرات صغيرة بين الدفعات، وفكر في استخدام الإنشاءات الإضافية (ISR في Next.js أو Astro's incremental content collections) لتجنب إعادة بناء كل شيء مرة واحدة.