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

.NET 7中RateLimiting问题:触发限制时仅拦截请求的单个端点

解决.NET 7中限流仅针对单个端点+IP的问题

你的问题出在使用了全局限流器(GlobalLimiter),这会对所有端点生效,且当前分区键用的是Host(主机名)而非用户IP,导致同一主机下所有请求共享限流计数器,触发限制时所有端点都被拦截。以下是修改方案:

1. 定义端点级别的限流策略

在ConfigureServices中,取消全局限流器,改为定义命名的限流策略,按「用户IP + 端点路径」作为分区键,确保每个IP对单个端点的请求单独计数:

services.AddRateLimiter(options =>
{
    // 命名策略:PerIpPerEndpoint,针对每个IP的每个端点单独限流
    options.AddPolicy("PerIpPerEndpoint", context =>
        RateLimitPartition.GetFixedWindowLimiter(
            // 分区键:用户IP + 请求路径,确保每个IP对每个端点独立计数
            partitionKey: $"{context.Connection.RemoteIpAddress}-{context.Request.Path}",
            factory: _ => new FixedWindowRateLimiterOptions
            {
                AutoReplenishment = true,
                PermitLimit = 5,
                QueueLimit = 0,
                Window = TimeSpan.FromSeconds(20)
            }));

    options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
});

2. 为指定端点绑定限流策略

在Configure方法中,仅对需要限流的端点应用该策略,其他端点不受影响:

app.UseRouting();

// 限流中间件必须放在路由之后、端点配置之前
app.UseRateLimiter();

app.UseEndpoints(endpoints =>
{
    // 对目标端点应用限流策略
    endpoints.MapGet("/api/your-target-endpoint", async context =>
    {
        await context.Response.WriteAsync("处理请求的逻辑");
    }).RequireRateLimiting("PerIpPerEndpoint");

    // 其他端点无需限流,正常访问
    endpoints.MapGet("/api/other-endpoint", async context =>
    {
        await context.Response.WriteAsync("不受限流的端点");
    });
});

关键说明

  • 分区键设计:通过RemoteIpAddress(用户IP)和Request.Path(端点路径)组合,保证每个IP对不同端点的限流计数完全独立,不会互相干扰。
  • 策略绑定:仅对需要限流的端点调用RequireRateLimiting,未绑定的端点不受限流规则限制。
  • 中间件顺序:UseRateLimiter必须放在UseRouting之后、UseEndpoints之前,才能正确获取请求上下文的IP和路径信息。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 17:42:55