PHP项目漏斗限流如何多层过滤异常请求

wen PHP项目 25

本文目录导读:

PHP项目漏斗限流如何多层过滤异常请求

  1. 总体架构
  2. 第一层:基础IP限流
  3. 第二层:用户行为分析
  4. 第三层:业务规则验证
  5. 第四层:分布式协同限流
  6. 第五层:实时监控与降级
  7. 完整过滤器链配置
  8. 最佳实践建议

针对PHP项目的漏斗限流多层过滤异常请求,我提供一个完整的分层设计方案:

总体架构

// 多层过滤器链
class FilterChain {
    private array $filters = [];
    public function addFilter(FilterInterface $filter): void {
        $this->filters[] = $filter;
    }
    public function execute(Request $request): bool {
        foreach ($this->filters as $filter) {
            if (!$filter->handle($request)) {
                return false; // 请求被拦截
            }
        }
        return true;
    }
}

第一层:基础IP限流

class IPRateLimiter implements FilterInterface {
    private Redis $redis;
    private array $config;
    public function __construct(Redis $redis) {
        $this->redis = $redis;
        $this->config = [
            'single_ip' => 100,      // 单IP每分钟限制
            'ip_segment' => 500,      // IP段限制
            'threshold' => 0.8        // 触发熔断阈值
        ];
    }
    public function handle(Request $request): bool {
        $ip = $request->getClientIp();
        $ipSegment = $this->getIpSegment($ip);
        // 使用漏斗算法
        $singleKey = "rate_limit:ip:{$ip}";
        $segmentKey = "rate_limit:segment:{$ipSegment}";
        // 检查是否触发熔断
        if ($this->isCircuitBroken($singleKey)) {
            $this->blockRequest($request, 'IP熔断');
            return false;
        }
        // 漏斗算法检查
        return $this->leakyBucketCheck($singleKey, $this->config['single_ip']) 
            && $this->leakyBucketCheck($segmentKey, $this->config['ip_segment']);
    }
    private function leakyBucketCheck(string $key, int $capacity): bool {
        $current = $this->redis->get($key) ?: 0;
        $this->redis->multi();
        $this->redis->incr($key);
        $this->redis->expire($key, 60); // 60秒过期
        $this->redis->exec();
        return $current < $capacity;
    }
}

第二层:用户行为分析

class BehaviorAnalyzer implements FilterInterface {
    private array $patterns = [];
    private MLService $mlService;
    public function handle(Request $request): bool {
        // 提取行为特征
        $features = $this->extractFeatures($request);
        // 规则引擎检查
        if (!$this->ruleCheck($features)) {
            return false;
        }
        // 机器学习模型评分(可选)
        if ($this->isHighRisk($features)) {
            $score = $this->mlService->predict($features);
            if ($score > 0.8) {
                $this->blockRequest($request, 'ML检测异常');
                return false;
            }
        }
        return true;
    }
    private function extractFeatures(Request $request): array {
        return [
            'request_interval' => $this->calcRequestInterval($request), // 请求间隔
            'browser_fingerprint' => $this->getFingerprint($request), // 浏览器指纹
            'user_agent' => $request->userAgent(),
            'page_access_order' => $this->getAccessOrder($request), // 页面访问顺序
            'mouse_movements' => $this->getMouseData($request), // 鼠标轨迹
            'js_environment' => $this->checkJSEnvironment($request) // JavaScript环境检测
        ];
    }
    private function ruleCheck(array $features): bool {
        // 检查异常行为模式
        $rules = [
            'too_fast' => $features['request_interval'] < 0.1, // 100ms内多次请求
            'suspicious_ua' => $this->isSuspiciousUA($features['user_agent']),
            'abnormal_order' => $this->isAbnormalAccessOrder($features['page_access_order']),
            'no_js' => !$features['js_environment'] // 无JavaScript环境
        ];
        $violations = array_filter($rules);
        if (count($violations) >= 2) {
            return false; // 触发多条规则则拦截
        }
        return true;
    }
}

第三层:业务规则验证

class BusinessValidator implements FilterInterface {
    private RuleEngine $ruleEngine;
    private array $threshold = [];
    public function handle(Request $request): bool {
        // 获取请求的业务上下文
        $context = $this->getBusinessContext($request);
        // 执行业务规则
        $result = $this->ruleEngine->evaluate([
            new RateLimitRule($context, 1000), // 整体业务限制
            new ResourceRule($context, 500),   // 资源操作限制
            new SceneRule($context, 200)       // 特定场景限制
        ]);
        if (!$result->isPass()) {
            $this->recordRiskEvent($request, $result);
            return false;
        }
        // 动态阈值调整
        $this->adjustThreshold($request);
        return true;
    }
    private function getBusinessContext(Request $request): array {
        return [
            'user_id' => $request->getUserId(),
            'action' => $request->getAction(),    // 操作类型
            'resource' => $request->getResource(), // 操作资源
            'timestamp' => time(),
            'device_id' => $request->getDeviceId(),
            'scene' => $request->getScene()        // 业务场景
        ];
    }
    private function adjustThreshold(Request $request): void {
        // 根据实时数据动态调整阈值
        $currentLoad = $this->getCurrentSystemLoad();
        $timeKey = date('H:i');
        // 高峰时段降低阈值
        if (in_array($timeKey, $this->config['peak_hours'])) {
            $this->threshold['business'] *= 0.7;
        }
        // 系统负载高时收紧限流
        if ($currentLoad > 0.8) {
            $this->threshold['resource'] *= 0.5;
        }
    }
}

第四层:分布式协同限流

class DistributedLimiter implements FilterInterface {
    private Redis $redis;
    private array $nodeConfig;
    public function handle(Request $request): bool {
        $userId = $request->getUserId();
        $globalKey = "global_limit:user:{$userId}";
        // 获取全局限制策略
        $globalLimit = $this->getGlobalLimit($userId);
        // 使用Redis实现分布式漏斗
        $tokens = $this->redis->get($globalKey);
        $now = microtime(true);
        if ($tokens === false) {
            // 初始化漏斗
            $this->redis->set($globalKey, json_encode([
                'tokens' => $globalLimit['capacity'],
                'last_time' => $now,
                'leak_rate' => $globalLimit['rate']
            ]));
            return true;
        }
        $data = json_decode($tokens, true);
        // 计算漏出的令牌
        $elapsed = $now - $data['last_time'];
        $leaked = floor($elapsed * $data['leak_rate']);
        $data['tokens'] = min($data['tokens'] + $leaked, $globalLimit['capacity']);
        $data['last_time'] = $now;
        if ($data['tokens'] <= 0) {
            $this->notifyOtherNodes($request);
            return false;
        }
        $data['tokens']--;
        $this->redis->set($globalKey, json_encode($data), 60);
        return true;
    }
}

第五层:实时监控与降级

class MonitorAndDegrade implements FilterInterface {
    private MetricsCollector $metrics;
    private AlertManager $alert;
    private ServiceRegistry $registry;
    public function handle(Request $request): bool {
        // 收集实时指标
        $metrics = $this->collectMetrics();
        // 检查是否需要降级
        if ($this->needDegrade($metrics)) {
            $this->executeDegradeStrategy($request);
            return false;
        }
        // 自适应限流
        if ($this->isAdaptiveLimit($metrics)) {
            return $this->adaptiveLimit($request, $metrics);
        }
        return true;
    }
    private function needDegrade(array $metrics): bool {
        $thresholds = [
            'error_rate' => 0.05,      // 错误率超过5%
            'response_time' => 2000,   // 响应时间超过2秒
            'cpu_usage' => 0.85,       // CPU使用率超过85%
            'memory_usage' => 0.80     // 内存使用率超过80%
        ];
        foreach ($thresholds as $key => $value) {
            if ($metrics[$key] > $value) {
                return true;
            }
        }
        return false;
    }
    private function executeDegradeStrategy(Request $request): void {
        // 获取当前服务的降级策略
        $strategy = $this->registry->getDegradeStrategy($request->getService());
        switch ($strategy) {
            case 'direct_reject':
                // 直接拒绝
                $this->rejectRequest($request);
                break;
            case 'cache_only':
                // 仅使用缓存
                $this->serveFromCache($request);
                break;
            case 'rate_reduce':
                // 降低处理速率
                $this->reduceRate($request, 50);
                break;
            case 'mock_response':
                // 返回模拟数据
                $this->mockResponse($request);
                break;
        }
    }
}

完整过滤器链配置

class RateLimitManager {
    private FilterChain $chain;
    public function __construct(Redis $redis) {
        $this->chain = new FilterChain();
        // 按顺序添加过滤器
        $this->chain->addFilter(new IPRateLimiter($redis));
        $this->chain->addFilter(new BehaviorAnalyzer());
        $this->chain->addFilter(new BusinessValidator());
        $this->chain->addFilter(new DistributedLimiter($redis));
        $this->chain->addFilter(new MonitorAndDegrade());
    }
    public function process(Request $request): void {
        if (!$this->chain->execute($request)) {
            // 记录被拦截的请求
            Log::warning('Request blocked', [
                'ip' => $request->getClientIp(),
                'uri' => $request->getUri(),
                'filter' => $request->getBlockedFilter()
            ]);
            throw new RateLimitException('请求过于频繁');
        }
        // 正常处理请求
        $this->handleRequest($request);
    }
}

最佳实践建议

  1. 分级策略

    • 基础层拦截大量攻击
    • 行为层识别异常模式
    • 业务层控制合理使用
    • 分布式层保证全局公平
  2. 性能优化

    // 使用本地缓存减少Redis压力
    class LocalCacheLimiter {
        private array $localCache = [];
        private int $syncInterval = 5; // 5秒同步一次
        public function check(string $key): bool {
            $now = time();
            // 检查本地缓存
            if (isset($this->localCache[$key])) {
                $data = $this->localCache[$key];
                if ($now - $data['time'] < $this->syncInterval) {
                    return $data['allowed'];
                }
            }
            // 同步Redis数据
            $result = $this->syncFromRedis($key);
            $this->localCache[$key] = [
                'allowed' => $result,
                'time' => $now
            ];
            return $result;
        }
    }
  3. 监控与告警

    // 配置告警规则
    $alertRules = [
        'blocked_rate' => 0.1,    // 拦截率超过10%
        'false_positive' => 0.01, // 误杀率超过1%
        'latency_increase' => 20 // 延迟增加20%
    ];

这个多层漏斗限流方案提供了从网络层到业务层的全面防护,可以根据实际需求选择和组合各个过滤层。

抱歉,评论功能暂时关闭!