网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息

IP限流重构总结

🎯 重构目标达成

按照你的要求,我已经完成了IP限流功能的重构:

1. 封装到 Dpz.Core.Infrastructure

  • 创建了独立的 IpRateLimitService 服务
  • 提供了完整的接口和实现
  • 支持依赖注入和配置管理

2. 实现真正的限流

  • 延迟处理:超出限制的请求会被延迟,而不是直接拒绝
  • 排队机制:请求会等待一定时间后继续处理
  • 渐进式延迟:超出越多,延迟越长

🔧 新架构设计

分层结构

请求流程:
RateLimitMiddleware (第一层 - 限流)
    ↓
RejectBots (第二层 - 安全检查)
    ↓
业务逻辑 (第三层 - 正常处理)

职责分离

组件职责位置
IpRateLimitService核心限流逻辑Dpz.Core.Infrastructure
RateLimitMiddleware中间件集成Dpz.Core.Infrastructure
RejectBots安全规则检查Dpz.Core.Web.Middleware

🚀 核心特性

1. 真正的限流效果

// 原来的逻辑(简单拒绝)
if (超出限制) {
    return 403; // 直接拒绝
}

// 新的逻辑(延迟处理)
if (超出限制) {
    await Task.Delay(delayMs); // 延迟等待
    // 继续处理请求
}

2. 智能延迟计算

延迟时间 = 基础延迟 + (超出数量 × 延迟倍数)

例如:
- 第101次请求:1000ms (基础延迟)
- 第102次请求:1500ms (基础 + 1×500)
- 第105次请求:3500ms (基础 + 5×500)
- 最大限制:30000ms

3. 多种处理策略

public class RateLimitResult
{
    bool IsAllowed;     // 是否允许请求
    bool ShouldDelay;   // 是否需要延迟
    int DelayMs;        // 延迟时间
    string Message;     // 结果消息
}

// 三种结果:
Allow()          // 正常通过
RateLimit()      // 延迟处理
Block()          // 直接拒绝(封禁期)

📊 配置系统

完整的配置选项

{
  "RateLimit": {
    "WindowSizeMinutes": 5,          // 时间窗口
    "MaxRequestsPerWindow": 100,     // 窗口内最大请求
    "MaxBlocksPerWindow": 3,         // 窗口内最大拦截
    "BlockDurationMinutes": 30,      // 封禁时长
    "CleanupIntervalMinutes": 60,    // 清理间隔
    "BaseDelayMs": 1000,            // 基础延迟
    "DelayMultiplierMs": 500,       // 延迟倍数
    "MaxDelayMs": 30000             // 最大延迟
  }
}

灵活的服务注册

// 方式1:默认配置
services.AddIpRateLimit();

// 方式2:代码配置
services.AddIpRateLimit(config => {
    config.MaxRequestsPerWindow = 200;
    config.BaseDelayMs = 2000;
});

// 方式3:配置文件
services.AddIpRateLimit(Configuration, "RateLimit");

🔍 使用效果对比

原来的效果(简单拒绝)

客户端 → 超出限制 → 403错误 → 客户端重试 → 再次403 → 恶性循环

现在的效果(智能限流)

客户端 → 超出限制 → 延迟2秒 → 正常响应 → 客户端满意

实际体验差异

场景原来现在
正常用户可能被误杀稍有延迟但能正常使用
爬虫工具收到403后继续尝试延迟增加,自然放慢
恶意攻击达到拦截阈值后封禁同样封禁,但正常用户不受影响

🛡️ 安全性提升

多层防护

  1. 频率限制 → 延迟处理(体验友好)
  2. 拦截累积 → 临时封禁(30分钟)
  3. 安全规则 → 直接拒绝(恶意请求)

智能响应

// 根据不同情况返回不同状态码
200 + 延迟     // 频率超限但允许处理
429          // IP被封禁
403          // 违反安全规则

📈 监控和统计

详细的统计信息

var stats = rateLimitService.GetStats();
Console.WriteLine($"总跟踪IP: {stats.TotalTrackedIps}");
Console.WriteLine($"活跃IP: {stats.ActiveIps}");
Console.WriteLine($"被限流IP: {stats.RateLimitedIps}");  // 新增
Console.WriteLine($"被封禁IP: {stats.BlockedIps}");

响应头信息

X-RateLimit-Delay: 2000        // 延迟时间
X-RateLimit-Reason: 请求过于频繁  // 限流原因

结构化日志

INFO: 对IP 192.168.1.100 应用限流,延迟 2000ms,路径: /api/data
WARN: IP 192.168.1.101 超过请求限制,当前请求数: 105, 延迟: 3500ms
WARN: IP 192.168.1.102 因多次拦截被封禁,拦截次数: 3

🔧 集成方式

新的中间件配置

// Program.cs
builder.Services.AddIpRateLimit(Configuration);

// Configure pipeline
app.UseIpRateLimit();        // 第一层:限流
app.UseMiddleware<RejectBots>(); // 第二层:安全检查
app.UseRouting();            // 第三层:路由
// ... 其他中间件

RejectBots 职责简化

// 移除了内置的IP限流代码
// 专注于安全规则检查
// 向限流服务报告拦截事件
rateLimitService?.RecordBlock(clientIp);

🎯 性能优势

内存效率

  • 分离关注点:限流和安全检查独立
  • 按需清理:过期记录自动清理
  • 并发安全:使用 ConcurrentDictionary

处理效率

  • 早期处理:限流在管道早期进行
  • 智能延迟:只对超限请求延迟
  • 异步清理:不阻塞主要处理流程

🚀 未来扩展性

分布式支持

// 可以扩展为分布式缓存
public class DistributedIpRateLimitService : IIpRateLimitService
{
    private readonly IDistributedCache _cache;
    // 使用Redis等实现跨实例限流
}

白名单机制

// 可以添加白名单功能
public bool IsWhitelisted(string ip) => 
    _config.WhitelistIps.Contains(ip);

动态配置

// 可以支持运行时配置更新
public void UpdateConfig(RateLimitConfig newConfig) =>
    _config = newConfig;

📋 测试覆盖

创建了完整的测试套件:

  • ✅ 正常请求处理
  • ✅ 限流延迟计算
  • ✅ 封禁机制测试
  • ✅ 统计信息验证
  • ✅ 并发访问测试
  • ✅ 边界条件测试

🎉 总结

通过这次重构,我们实现了:

你的核心需求

  • 封装到基础设施层:独立的服务,便于复用
  • 真正的限流效果:延迟处理而不是简单拒绝
  • 排队机制:请求等待后继续处理

额外的价值

  • 更好的用户体验:正常用户不会被误杀
  • 更智能的防护:渐进式限制,自适应调节
  • 更完善的监控:详细的统计和日志
  • 更灵活的配置:支持多种配置方式

企业级特性

  • 高性能:毫秒级处理,内存高效
  • 高可靠:并发安全,异常处理
  • 易维护:清晰的架构,完整的测试
  • 可扩展:支持未来的分布式部署

现在你的应用具备了真正意义上的"限流"能力,既能保护系统安全,又能提供良好的用户体验!🚀

loading