当前位置: 首页 > news >正文

.NET 接口限流、防重、幂等性设计

一、设计思路

 
表格

 
特性作用实现方式
限流 防止接口被刷、防止流量洪峰 令牌桶 / 滑动窗口 + Redis / 内存缓存
防重 防止前端重复点击 / 网络重试重复提交 请求唯一 ID + 短时间锁
幂等性 保证接口重复调用结果一致 唯一业务键 + 状态机 + 分布式锁
 

 

二、.NET 完整实现代码

 

1. 依赖安装

 
Install-Package AspNetCoreRateLimit # 限流
Install-Package StackExchange.Redis # Redis
Install-Package MediatR # 可选
Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
 

 

2. 接口限流

 
使用 AspNetCoreRateLimit,支持 IP 限流、客户端限流。
 

appsettings.json

 
"IpRateLimiting": {"EnableEndpointRateLimiting": true,"StackBlockedRequests": false,"HttpStatusCode": 429,"GeneralRules": [{"Endpoint": "*","Period": "1s","Limit": 10  // 每秒最多 10 次},{"Endpoint": "POST:/api/order","Period": "1s","Limit": 2   // 订单接口每秒最多 2 次}]
}
 

Program.cs 注册

 
builder.Services.AddMemoryCache();
builder.Services.AddInMemoryRateLimiting();
builder.Services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>();app.UseIpRateLimiting(); // 必须放在路由之前
 
限流返回:429 Too Many Requests
 

 

3. 防重复提交

 
核心:请求唯一 ID(RequestId)+ 短时间锁
 
前端提交时携带 Request-Id 头,后端校验是否重复。
 

防重过滤器 / 中间件

 
/// <summary>
/// 防重复提交特性
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class IdempotentAttribute : Attribute
{/// <summary>/// 锁过期时间(秒)/// </summary>public int ExpireSeconds { get; set; } = 5;
}
 

防重过滤器

 
public class IdempotentFilter : IAsyncActionFilter
{private readonly IDistributedCache _cache;public IdempotentFilter(IDistributedCache cache){_cache = cache;}public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next){// 只拦截 POST/PUT/DELETEvar method = context.HttpContext.Request.Method;if (method is "GET" or "HEAD"){await next();return;}// 获取请求唯一 ID(前端传入 Header)if (!context.HttpContext.Request.Headers.TryGetValue("Request-Id", out var requestId)){context.Result = new JsonResult(new { code = 400, msg = "缺少 Request-Id" });return;}var attr = context.ActionDescriptor.EndpointMetadata.OfType<IdempotentAttribute>().FirstOrDefault();var key = $"req:lock:{requestId}";// 已存在 = 重复提交var exists = await _cache.GetStringAsync(key);if (!string.IsNullOrEmpty(exists)){context.Result = new JsonResult(new { code = 429, msg = "请勿重复提交" });return;}// 加锁await _cache.SetStringAsync(key, "1", new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(attr?.ExpireSeconds ?? 5)});await next();}
}
 

注册

 
builder.Services.AddScoped<IdempotentFilter>();
builder.Services.AddDistributedRedisCache(options =>
{options.Configuration = "localhost:6379";
});builder.Services.AddControllers(o =>
{o.Filters.Add<IdempotentFilter>();
});
 

使用

 
[HttpPost("order")]
[Idempotent(ExpireSeconds = 10)] // 10 秒内防重
public async Task<IActionResult> CreateOrder(OrderDto dto)
 

 

4. 幂等性设计

 

幂等性定义

 
同一个请求执行 1 次和执行 N 次,结果完全一样,不会产生脏数据。
 
适用场景:
 
  • 支付
  • 订单创建
  • 退款
  • 表单提交
  • 回调接口
 

实现方案

 

步骤

 
  1. 前端获取 token(幂等号)
  2. 提交时携带 token
  3. 后端使用 分布式锁 + 状态机 保证只执行一次
 

代码实现

 

1)获取幂等 Token

 
[HttpGet("token")]
public async Task<IActionResult> GetIdempotentToken()
{var token = Guid.NewGuid().ToString("N");await _cache.SetStringAsync($"idt:{token}", "ok", TimeSpan.FromMinutes(10));return Ok(new { token });
}
 

2)幂等接口

 
[HttpPost("pay")]
public async Task<IActionResult> Pay(PayRequest dto)
{if (string.IsNullOrEmpty(dto.IdempotentToken))return BadRequest("缺少幂等Token");var lockKey = $"lock:pay:{dto.IdempotentToken}";// 分布式锁(只有一个请求能进入)var lockTaken = await _cache.GetStringAsync(lockKey);if (!string.IsNullOrEmpty(lockTaken))return Ok(new { code = 200, msg = "已支付,请勿重复提交" });await _cache.SetStringAsync(lockKey, "1", TimeSpan.FromMinutes(5));try{// 1. 查询订单是否已处理var order = await _db.Orders.FirstOrDefaultAsync(o => o.OrderNo == dto.OrderNo);if (order?.Status == PayStatus.Success)return Ok(new { code = 200, msg = "成功" });// 2. 执行业务await DoPay(dto);// 3. 更新状态(关键!)order.Status = PayStatus.Success;await _db.SaveChangesAsync();return Ok(new { code = 200, msg = "支付成功" });}catch{// 失败释放锁,允许重试await _cache.RemoveAsync(lockKey);throw;}
}
 

 

三、三者区别

 
表格
 
名称目的范围
限流 保护服务器不被打垮 频率控制
防重 防止短时间重复点击 请求唯一 ID
幂等性 保证多次调用结果一致 业务唯一键
 

 

四、实践

 
  1. 防重 + 幂等一起用
    • 防重:前端快速重复点击
    • 幂等:网络重试、回调重试、消息重试
     
  2. 限流放在网关层最好(Kong / YARP)
  3. 幂等必须依赖数据库状态
     
    不能只靠缓存,缓存丢了会出问题
  4. POST/PUT/DELETE 必须幂等
  5. 防重时间 5~10 秒,幂等时间 5~30 分钟
 

 

总结

 
  • 限流:保护服务,控制请求频率
  • 防重:防止重复提交,依赖 RequestId
  • 幂等性:保证结果一致,依赖 Token + 状态机
  • 三者组合使用,是企业级 API 安全标准方案
http://www.jsqmd.com/news/775569/

相关文章:

  • com0com实战指南:Windows虚拟串口深度解析与效率提升
  • 5分钟完成Degrees of Lewdity游戏美化:DoL-Lyra整合包完整指南
  • 3大痛点解析:如何深度优化AMD处理器性能并实现游戏帧率稳定提升
  • 2026最新防火卷帘门/防火门/防火窗/单元门/钢质门企业推荐!辽宁优质权威榜单发布,沈阳靠谱企业实力入围 - 十大品牌榜
  • 内容创作团队如何利用多模型能力批量生成与优化文案
  • 武汉室内设计公司靠谱吗?UWD有无设计告诉你 - mypinpai
  • 如何快速解决中文文献管理难题:终极茉莉花插件使用指南
  • 开源AI技能库:标准化与复用,提升智能体开发效率
  • 广州西服定制推荐,精选进口面料,每一寸都是高级感 - 十大品牌榜
  • 如何快速掌握wxappUnpacker:微信小程序逆向工程的完整实战指南
  • 大润发购物卡回收流程详解,新手小白也能秒懂! - 团团收购物卡回收
  • 2026年北京井木装饰在服装行业的排名,有名的装修公司推荐 - mypinpai
  • Windows右键菜单如何告别杂乱?这款专业管理工具给你终极解决方案
  • B-52轰炸机内部,没有MCU的时代,一台纯机械设备,竟能计算天空坐标
  • Company Registered Address 2026.05.06
  • Adobe Acrobat Pro 2025下载安装使用教程
  • 永辉超市购物卡换现金,这些平台帮你高价回收 - 团团收购物卡回收
  • AI代理协作自动化生成n8n工作流:从需求到生产部署全流程
  • 智能防抖解决方案:KeyboardChatterBlocker在机械键盘输入优化领域的应用
  • KiCad 3D模型库不够用?试试这个骚操作:把立创EDA的封装变成你的私人模型库
  • InnoDB 中索引类型有哪些?
  • 2026年论文降低AI率收藏指南:学姐实测AIGC免费降重,盘点5款实用降AI率工具 - 降AI实验室
  • 毫米波测量技术:W波段矢量网络分析仪应用指南
  • 2026年靠谱的西门子代理品牌排名 - mypinpai
  • CentOS7上如何把密码行迁移到其他Linux发行版上
  • Java游戏开发实践:从ECS架构到经典游戏实现
  • Windows系统RpcRtRemote.dll文件丢失无法启动程序解决
  • MTKClient终极指南:联发科设备底层调试与刷机救砖完全教程
  • Redis--哨兵机制与CAP定理
  • 从单体到模块化:使用pattern8实现DDD架构重构与自动化工具实践