تخيل أنك تدير متجرًا إلكترونيًا مبني بـ Laravel، وفجأة أعلنت عن تخفيضات Black Friday بنسبة 70%. في غضون دقائق، تتدفق آلاف الطلبات في نفس اللحظة على الـ API الخاص بك. السؤال الحاسم هنا: هل سيصمد نظامك أم سينهار تحت هذا الضغط الهائل؟
في عالم تطوير الأنظمة الحديثة، لا يكفي أن يكون الـ API الخاص بك سريعًا وفعالًا في الظروف العادية. المعيار الحقيقي للجودة هو: هل يمكن لنظامك أن يظل مستقرًا وموثوقًا حتى في أسوأ السيناريوهات؟
هذا ما يُعرف بـ Resilience أو المرونة - القدرة على الاستمرار في العمل حتى تحت ضغط شديد، مع الحفاظ على تجربة مستخدم مقبولة. في هذا المقال المخصص لمطوري Laravel، سنستكشف الاستراتيجيات الست الأساسية التي تضمن لك بناء أنظمة قادرة على مواجهة أي ضغط.
ما هو Rate Limiting؟
Rate Limiting هو آلية للتحكم في عدد الطلبات التي يمكن أن يرسلها مستخدم أو عميل معين خلال فترة زمنية محددة. يعمل كخط دفاع أول ضد التحميل الزائد والهجمات المحتملة مثل DDoS.
لماذا هو ضروري؟
الحماية من الإجهاد: يمنع إرسال آلاف الطلبات في ثوانٍ معدودة
العدالة في الاستخدام: يضمن توزيع الموارد بشكل عادل بين جميع المستخدمين
الحماية من الهجمات: يكتشف ويوقف محاولات إساءة الاستخدام
التحكم في التكاليف: يحد من استهلاك الموارد والخدمات السحابية
التطبيق العملي في Laravel
Laravel يوفر نظام Rate Limiting قوي ومرن من خلال middleware throttle و RateLimiter Facade.
الطريقة الأولى: Rate Limiting بسيط على مستوى الـ Routes
php// في ملف routes/api.php
use Illuminate\Support\Facades\Route;
// تحديد 60 طلب في الدقيقة
Route::middleware(['throttle:60,1'])->group(function () {
Route::get('/products', [ProductController::class, 'index']);
Route::post('/orders', [OrderController::class, 'store']);
});الطريقة الثانية: Rate Limiting مخصص في AppServiceProvider
يمكنك إنشاء قواعد rate limiting مخصصة ومعقدة في App\Providers\AppServiceProvider.php:
php
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Http\Request;
public function boot(): void
{
// Rate limiting أساسي للـ API
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
// Rate limiting مخصص للمستخدمين المميزين
RateLimiter::for('premium', function (Request $request) {
return $request->user()?->isPremium()
? Limit::perMinute(200)->by($request->user()->id)
: Limit::perMinute(60)->by($request->ip());
});
// Rate limiting ديناميكي حسب subscription level
RateLimiter::for('flexible', function (Request $request) {
if ($request->user()) {
$limit = match($request->user()->subscription_tier) {
'free' => 10,
'basic' => 60,
'pro' => 200,
'enterprise' => 1000,
default => 30
};
return Limit::perMinute($limit)->by($request->user()->id);
}
return Limit::perMinute(10)->by($request->ip());
});
}تطبيق Rate Limiting على الـ Routes
php// استخدام rate limiter مخصص
Route::middleware(['auth:sanctum', 'throttle:premium'])->group(function () {
Route::post('/upload', [FileController::class, 'upload']);
});
// rate limiting مختلف لـ endpoints مختلفة
Route::post('/login', [AuthController::class, 'login'])
->middleware('throttle:5,1'); // 5 محاولات في الدقيقة
Route::middleware(['auth:sanctum', 'throttle:flexible'])->group(function () {
Route::apiResource('posts', PostController::class);
});
Rate Limiting متقدم مع Sliding Window
Laravel 10+ يدعم Sliding Window للتوزيع الأفضل للطلبات:
phpRateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)
->by($request->user()?->id ?: $request->ip())
->response(function (Request $request, array $headers) {
return response()->json([
'message' => 'تم تجاوز الحد المسموح من الطلبات. يرجى المحاولة لاحقاً.',
'retry_after' => $headers['Retry-After'] ?? 60
], 429, $headers);
});
});استخدام Redis لـ Rate Limiting
لتحسين الأداء في التطبيقات الكبيرة، استخدم Redis:
env# في ملف .env
CACHE_DRIVER=redis
REDIS_CLIENT=phpredis
php// Rate limiting باستخدام Redis
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(100)
->by($request->user()?->id ?: $request->ip())
->using(cache()->driver('redis'));
});