- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
338 lines
8.9 KiB
Markdown
338 lines
8.9 KiB
Markdown
# RateLimit to SlidingWindow Migration Guide
|
|
|
|
This guide explains how to migrate from the legacy RateLimit implementation to the new SlidingWindow-based system.
|
|
|
|
## Overview
|
|
|
|
The RateLimit module has been refactored to use the SlidingWindow module for better performance, accuracy, and advanced analytics. The new implementation provides:
|
|
|
|
- **Improved Accuracy**: True sliding window instead of fixed windows
|
|
- **Advanced Analytics**: Burst detection, threat analysis, and pattern recognition
|
|
- **Better Performance**: Optimized data structures and caching
|
|
- **Unified Architecture**: Consistent with other framework modules
|
|
|
|
## Key Changes
|
|
|
|
### 1. New Classes
|
|
|
|
- `SlidingWindowRateLimiter`: Modern rate limiter using SlidingWindow
|
|
- `SlidingWindowTokenBucket`: Token bucket with analytics
|
|
- `RateLimitAggregator`: Advanced analytics aggregator
|
|
- `RateLimitResult`: Enhanced result object (already existing)
|
|
|
|
### 2. Backwards Compatibility
|
|
|
|
The old `RateLimiter` class is still available and functional. No breaking changes to existing API.
|
|
|
|
## Migration Steps
|
|
|
|
### Step 1: Update Dependency Injection
|
|
|
|
```php
|
|
// Old way (still works)
|
|
$rateLimiter = $container->get(RateLimiter::class);
|
|
|
|
// New way (recommended)
|
|
$rateLimiter = $container->get(SlidingWindowRateLimiter::class);
|
|
|
|
// Or use alias
|
|
$rateLimiter = $container->get('rate_limiter'); // Points to SlidingWindow version
|
|
```
|
|
|
|
### Step 2: Basic Rate Limiting Migration
|
|
|
|
```php
|
|
// Old implementation
|
|
$rateLimiter = new RateLimiter(new CacheStorage($cache));
|
|
$result = $rateLimiter->checkLimit('user:123', 10, 60);
|
|
|
|
// New implementation
|
|
$windowFactory = new SlidingWindowFactory($cache);
|
|
$rateLimiter = new SlidingWindowRateLimiter($windowFactory);
|
|
$result = $rateLimiter->checkLimit('user:123', 10, 60);
|
|
|
|
// API is identical, but implementation is more accurate
|
|
```
|
|
|
|
### Step 3: Enhanced Analytics (New Feature)
|
|
|
|
```php
|
|
// New advanced analytics capability
|
|
$requestContext = [
|
|
'client_ip' => $_SERVER['REMOTE_ADDR'],
|
|
'user_agent' => $_SERVER['HTTP_USER_AGENT'],
|
|
'request_path' => $_SERVER['REQUEST_URI']
|
|
];
|
|
|
|
$result = $rateLimiter->checkLimitWithAnalysis('user:123', 10, 60, $requestContext);
|
|
|
|
// Check for security threats
|
|
if ($result->isAttackSuspected()) {
|
|
// Handle potential attack
|
|
$threatLevel = $result->getThreatLevel(); // 'low', 'medium', 'high', 'critical'
|
|
$patterns = $result->attackPatterns; // ['burst_attack', 'volumetric_attack']
|
|
}
|
|
|
|
// Check for anomalous traffic
|
|
if ($result->hasAnomalousTraffic()) {
|
|
$deviation = $result->baselineDeviation;
|
|
// Implement adaptive response
|
|
}
|
|
```
|
|
|
|
### Step 4: Token Bucket Migration
|
|
|
|
```php
|
|
// Old token bucket (through RateLimiter)
|
|
$result = $rateLimiter->checkTokenBucket('api:service', 100, 10, 5);
|
|
|
|
// New dedicated token bucket with analytics
|
|
$tokenBucket = new SlidingWindowTokenBucket(
|
|
identifier: 'api:service',
|
|
capacity: 100,
|
|
refillRate: 10,
|
|
windowFactory: $windowFactory
|
|
);
|
|
|
|
$result = $tokenBucket->consumeWithAnalysis(5, $requestContext);
|
|
```
|
|
|
|
### Step 5: Update Middleware/Controllers
|
|
|
|
```php
|
|
class RateLimitMiddleware
|
|
{
|
|
public function __construct(
|
|
// Old
|
|
// private RateLimiter $rateLimiter
|
|
|
|
// New
|
|
private SlidingWindowRateLimiter $rateLimiter
|
|
) {}
|
|
|
|
public function handle($request, $next)
|
|
{
|
|
$clientId = $this->getClientId($request);
|
|
|
|
// Enhanced with threat analysis
|
|
$result = $this->rateLimiter->checkLimitWithAnalysis(
|
|
$clientId,
|
|
100,
|
|
300,
|
|
[
|
|
'client_ip' => $request->getClientIp(),
|
|
'user_agent' => $request->getUserAgent(),
|
|
'request_path' => $request->getPath()
|
|
]
|
|
);
|
|
|
|
if (!$result->isAllowed()) {
|
|
return $this->createRateLimitResponse($result);
|
|
}
|
|
|
|
// Log security events
|
|
if ($result->shouldLogSecurityEvent()) {
|
|
$this->logSecurityEvent($result);
|
|
}
|
|
|
|
return $next($request);
|
|
}
|
|
}
|
|
```
|
|
|
|
## Configuration Changes
|
|
|
|
### Environment Variables
|
|
|
|
No changes to existing environment variables. New optional variables:
|
|
|
|
```env
|
|
# SlidingWindow-specific settings
|
|
RATE_LIMIT_PERSISTENT=true
|
|
RATE_LIMIT_BURST_THRESHOLD=0.8
|
|
RATE_LIMIT_MIN_INTERVAL_THRESHOLD=2.0
|
|
|
|
# Advanced analytics
|
|
RATE_LIMIT_THREAT_ANALYSIS_ENABLED=true
|
|
RATE_LIMIT_BASELINE_TRACKING_ENABLED=true
|
|
```
|
|
|
|
### Container Configuration
|
|
|
|
```php
|
|
// In your service provider or bootstrap
|
|
$container->bind(SlidingWindowRateLimiter::class, function ($container) {
|
|
$cache = $container->get(Cache::class);
|
|
$windowFactory = new SlidingWindowFactory($cache);
|
|
|
|
return new SlidingWindowRateLimiter(
|
|
$windowFactory,
|
|
persistent: $_ENV['RATE_LIMIT_PERSISTENT'] ?? true
|
|
);
|
|
});
|
|
```
|
|
|
|
## Performance Improvements
|
|
|
|
### Memory Usage
|
|
- **Reduced**: Optimized data structures in SlidingWindow module
|
|
- **Efficient**: Smart cleanup of expired data
|
|
|
|
### Processing Speed
|
|
- **Faster**: Batch operations and optimized algorithms
|
|
- **Scalable**: Better performance under high load
|
|
|
|
### Accuracy
|
|
- **Precise**: True sliding window vs. fixed window approximation
|
|
- **Consistent**: Uniform distribution of requests over time
|
|
|
|
## New Features
|
|
|
|
### 1. Burst Detection
|
|
```php
|
|
$analytics = $rateLimiter->getAdvancedAnalytics('user:123', 60);
|
|
if ($analytics['burst_analysis']['burst_detected']) {
|
|
// Handle burst attack
|
|
}
|
|
```
|
|
|
|
### 2. Threat Analysis
|
|
```php
|
|
$result = $rateLimiter->checkLimitWithAnalysis($key, $limit, $window, $context);
|
|
$threatScore = $result->threatScore->getValue(); // 0-100
|
|
$recommendedActions = $result->getRecommendedStrategy();
|
|
```
|
|
|
|
### 3. Adaptive Responses
|
|
```php
|
|
// Automatically adjusts retry-after based on patterns
|
|
$retryAfter = $result->adaptiveRetryAfter->toSeconds();
|
|
|
|
// Multiple response strategies
|
|
foreach ($result->responseStrategies as $strategy) {
|
|
match ($strategy) {
|
|
'immediate_block' => $this->blockImmediately(),
|
|
'enhanced_monitoring' => $this->enableMonitoring(),
|
|
'captcha_challenge' => $this->requireCaptcha(),
|
|
};
|
|
}
|
|
```
|
|
|
|
## Testing Migration
|
|
|
|
### Unit Tests
|
|
```php
|
|
class SlidingWindowRateLimiterTest extends TestCase
|
|
{
|
|
public function test_basic_rate_limiting()
|
|
{
|
|
$cache = new InMemoryCache();
|
|
$windowFactory = new SlidingWindowFactory($cache);
|
|
$rateLimiter = new SlidingWindowRateLimiter($windowFactory);
|
|
|
|
// Test basic functionality
|
|
$result = $rateLimiter->checkLimit('test', 5, 60);
|
|
$this->assertTrue($result->isAllowed());
|
|
}
|
|
|
|
public function test_threat_detection()
|
|
{
|
|
// Test burst pattern detection
|
|
// Test anomaly detection
|
|
// Test attack pattern recognition
|
|
}
|
|
}
|
|
```
|
|
|
|
### Integration Tests
|
|
```php
|
|
class RateLimitIntegrationTest extends TestCase
|
|
{
|
|
public function test_middleware_integration()
|
|
{
|
|
// Test with actual HTTP requests
|
|
// Test threat detection in middleware
|
|
// Test performance under load
|
|
}
|
|
}
|
|
```
|
|
|
|
## Monitoring and Observability
|
|
|
|
### Metrics to Track
|
|
```php
|
|
// Basic metrics (existing)
|
|
- rate_limit_requests_allowed
|
|
- rate_limit_requests_blocked
|
|
- rate_limit_processing_time
|
|
|
|
// New metrics
|
|
- rate_limit_threats_detected
|
|
- rate_limit_burst_patterns
|
|
- rate_limit_baseline_deviations
|
|
- rate_limit_adaptive_responses
|
|
```
|
|
|
|
### Logging
|
|
```php
|
|
// Enhanced logging with threat context
|
|
if ($result->shouldLogSecurityEvent()) {
|
|
$logger->warning('Rate limit security event', [
|
|
'client_ip' => $result->clientIp,
|
|
'threat_level' => $result->getThreatLevel(),
|
|
'attack_patterns' => $result->attackPatterns,
|
|
'recommended_actions' => $result->getRecommendedStrategy()
|
|
]);
|
|
}
|
|
```
|
|
|
|
## Rollback Plan
|
|
|
|
If issues arise, you can easily rollback:
|
|
|
|
1. **Switch DI binding**:
|
|
```php
|
|
// Change from
|
|
$container->bind('rate_limiter', SlidingWindowRateLimiter::class);
|
|
// Back to
|
|
$container->bind('rate_limiter', RateLimiter::class);
|
|
```
|
|
|
|
2. **Update middleware**: Change constructor injection back to `RateLimiter`
|
|
|
|
3. **Remove new features**: Comment out threat analysis code
|
|
|
|
The old implementation remains fully functional and tested.
|
|
|
|
## Timeline
|
|
|
|
### Phase 1: Preparation (Week 1)
|
|
- Update DI container configuration
|
|
- Deploy alongside old implementation
|
|
- Update monitoring
|
|
|
|
### Phase 2: Gradual Migration (Week 2-3)
|
|
- Migrate non-critical endpoints
|
|
- Monitor performance and accuracy
|
|
- Test threat detection
|
|
|
|
### Phase 3: Full Migration (Week 4)
|
|
- Migrate critical endpoints
|
|
- Enable advanced analytics
|
|
- Full monitoring deployment
|
|
|
|
### Phase 4: Optimization (Week 5)
|
|
- Fine-tune threat detection thresholds
|
|
- Optimize performance based on metrics
|
|
- Remove old implementation if stable
|
|
|
|
## Support
|
|
|
|
For questions or issues during migration:
|
|
|
|
1. Check existing unit tests for usage examples
|
|
2. Review the `Examples/SlidingWindowRateLimitExample.php` file
|
|
3. Consult the SlidingWindow module documentation
|
|
4. Test thoroughly in staging environment
|
|
|
|
The migration is designed to be gradual and safe, with full backwards compatibility maintained. |