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

如何在NGINX中仅对成功请求(HTTP 200)开启速率限制?

仅对返回200的请求开启NGINX速率限制的实现方案

当然可以实现这个需求!你的场景是联系表单邮件发送,只需要限制成功提交(后端返回HTTP 200)的请求频率,失败请求不做限制,这需要调整NGINX的限速触发逻辑——默认的limit_req是请求到达时就统计,咱们得改成根据后端返回的状态码来决定是否计入限速统计。

核心思路

利用NGINX的map指令自定义一个变量,只有当后端返回200状态码时,这个变量才会带上客户端的IP地址;其他状态码下变量为空。然后基于这个变量创建限速区域,这样只有成功请求才会被纳入限速统计。

具体配置示例

http {
    # 定义映射规则:仅当后端返回200时,把客户端二进制IP赋值给$limited_ip,否则为空
    map $status $limited_ip {
        default "";
        200 $binary_remote_addr;
    }

    # 基于$limited_ip创建限速区域,只有非空的$limited_ip才会被统计
    limit_req_zone $limited_ip zone=success_only:10m rate=2r/m;

    server {
        location / {
            proxy_pass http://localhost:3000/;
            # 确保NGINX不拦截后端的错误状态码,让$status能拿到真实的返回码
            proxy_intercept_errors off;

            # 仅当$limited_ip非空(即返回200)时,触发限速规则
            limit_req zone=success_only nodelay;
            
            # 其他原有配置...
        }
        # 其他server配置...
    }
    # 其他http配置...
}

关键配置解释

  • map $status $limited_ip:这个指令是核心,它会根据后端返回的$status值动态设置$limited_ip。默认情况下变量为空,只有当状态码是200时,才会把客户端的二进制IP($binary_remote_addr,比普通IP更节省内存)赋值给它。
  • limit_req_zone $limited_ip ...:限速区域基于$limited_ip创建,空字符串不会被计入统计,所以只有成功请求才会占用这个区域的配额。
  • proxy_intercept_errors off:默认情况下NGINX会拦截4xx/5xx的错误状态码并返回自己的错误页面,开启这个参数可以让$status准确获取后端返回的真实状态码,保证映射规则生效。
  • nodelay参数:可选配置,如果不想让超出速率的成功请求排队等待,而是直接返回503错误,可以加上这个参数;如果允许短时间排队,可以去掉。

测试建议

  • 故意提交错误的表单(比如缺少必填字段),连续提交多次,验证是否不会触发限速。
  • 连续提交正确的表单,触发200返回,验证是否在每分钟2次后触发限速限制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:47:58