You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 7 限流实现:基于IP地址的请求频次限制

如何将现有固定窗口限流器改为基于IP地址限流(10秒内每个IP允许2次请求)

要实现按IP地址独立限流,你需要将全局统一的固定窗口限流器替换为分区限流器(PartitionedRateLimiter),让每个IP地址拥有专属的限流规则实例。具体修改如下:

核心修改思路

分区限流器会根据你指定的键(这里是客户端IP)为每个IP创建独立的限流窗口,确保不同IP的请求互不干扰,各自遵守「10秒内2次请求」的规则。

修改后的完整代码

app.UseRateLimiter(new RateLimiterOptions
{
    OnRejected = (context, _) =>
    {
        if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
        {
            context.HttpContext.Response.Headers.RetryAfter =
                ((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);

            app.Logger.LogWarning("请求超出限流阈值,请在{RetryAfter}秒后重试", retryAfter.TotalSeconds);
        }

        context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;

        return new ValueTask();
    }
}
// 每个IP在10秒内允许2次请求
.AddPartitionedRateLimiter("ip-fixed-window", context =>
{
    // 获取客户端IP地址,处理IP为空的边界情况
    var ipAddress = context.Connection.RemoteIpAddress?.ToString() ?? "unknown-ip";
    
    // 为每个IP创建独立的固定窗口限流规则
    return RateLimitPartition.GetFixedWindowLimiter(ipAddress, _ =>
        new FixedWindowRateLimiterOptions(2,
            window: TimeSpan.FromSeconds(10),
            queueProcessingOrder: QueueProcessingOrder.OldestFirst,
            queueLimit: 0,
            autoReplenishment: true));
}));

app.MapControllers().RequireRateLimiting("ip-fixed-window");

关键代码说明

  1. 替换限流注册方法:用AddPartitionedRateLimiter替代原有的AddFixedWindowLimiter,并指定分区键为客户端IP地址
  2. IP地址获取:通过context.Connection.RemoteIpAddress提取客户端IP,为避免空引用,添加了?? "unknown-ip"的默认值
  3. 独立规则实例:RateLimitPartition.GetFixedWindowLimiter会为每个IP创建单独的固定窗口限流实例,保证各IP的限流统计相互独立

内容的提问来源于stack exchange,提问作者nop

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 21:57:32