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

如何在.NET Core API中限制单端点每分钟的请求次数

.NET Core API 单端点限流实现方案

下面提供两种最常用的实现方式,可根据你使用的.NET版本选择:

方案1:.NET 7+ 内置限流中间件(推荐)

.NET 7及以上版本官方已经集成了开箱即用的限流组件,无需引入第三方包:

  • 第一步在Program.cs中注册限流服务并配置策略
var builder = WebApplication.CreateBuilder(args);

// 注册限流服务
builder.Services.AddRateLimiter(options =>
{
    // 定义1分钟5次请求的固定窗口限流策略
    options.AddFixedWindowLimiter(policyName: "PerMin5Limit", limiterOpts =>
    {
        limiterOpts.PermitLimit = 5;
        limiterOpts.Window = TimeSpan.FromMinutes(1);
        limiterOpts.QueueLimit = 0; // 超出限制直接拒绝,不排队
    });

    // 配置限流触发后的返回内容
    options.OnRejected = async (context, token) =>
    {
        context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
        await context.HttpContext.Response.WriteAsync("请求过于频繁,请1分钟后重试", cancellationToken: token);
    };
});

builder.Services.AddControllers();
// 其他服务注册逻辑...

var app = builder.Build();

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

app.MapControllers();

app.Run();
  • 第二步给目标端点绑定限流策略,直接在对应Action上加特性即可:
[ApiController]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
    [HttpGet] // 你要限流的目标端点
    [EnableRateLimiting("PerMin5Limit")]
    public IActionResult TestEndpoint()
    {
        return Ok("请求成功");
    }
}

方案2:自定义ActionFilter实现(兼容.NET 6及更低版本)

如果使用的是低于.NET 7的版本,可以自己实现轻量的限流过滤器:

  • 第一步创建限流特性类:
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Memory;

public class RateLimitAttribute : ActionFilterAttribute
{
    private readonly int _maxRequestCount;
    private readonly TimeSpan _limitWindow;

    public RateLimitAttribute(int maxRequestCount, int windowSeconds)
    {
        _maxRequestCount = maxRequestCount;
        _limitWindow = TimeSpan.FromSeconds(windowSeconds);
    }

    public override void OnActionExecuting(ActionExecutingContext context)
    {
        // 从请求容器获取缓存服务
        var cache = context.HttpContext.RequestServices.GetRequiredService<IMemoryCache>();
        // 用客户端IP+请求路径作为唯一计数键,按不同用户不同端点单独计数
        var clientIp = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown_ip";
        var cacheKey = $"rate_limit:{clientIp}:{context.HttpContext.Request.Path}";

        // 读取当前计数
        var currentCount = cache.Get<int>(cacheKey);
        if (currentCount >= _maxRequestCount)
        {
            context.Result = new ContentResult
            {
                StatusCode = StatusCodes.Status429TooManyRequests,
                Content = "请求过于频繁,请1分钟后重试"
            };
            return;
        }

        // 更新计数,缓存过期时间和限流窗口保持一致
        cache.Set(cacheKey, currentCount + 1, _limitWindow);
        base.OnActionExecuting(context);
    }
}
  • 第二步在Program.cs注册依赖的内存缓存服务:
builder.Services.AddMemoryCache();
builder.Services.AddControllers();
  • 第三步给目标端点加特性即可:
[HttpGet]
[RateLimit(5, 60)] // 参数:最大请求数、限流窗口秒数,即1分钟5次
public IActionResult TestEndpoint()
{
    return Ok("请求成功");
}

注意:如果是分布式多实例部署的场景,方案2需要把IMemoryCache替换为IDistributedCache(分布式缓存),避免各实例单独计数导致限流规则不准。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 06:15:01