本文目录导读:

针对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);
}
}
最佳实践建议
-
分级策略:
- 基础层拦截大量攻击
- 行为层识别异常模式
- 业务层控制合理使用
- 分布式层保证全局公平
-
性能优化:
// 使用本地缓存减少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; } } -
监控与告警:
// 配置告警规则 $alertRules = [ 'blocked_rate' => 0.1, // 拦截率超过10% 'false_positive' => 0.01, // 误杀率超过1% 'latency_increase' => 20 // 延迟增加20% ];
这个多层漏斗限流方案提供了从网络层到业务层的全面防护,可以根据实际需求选择和组合各个过滤层。