You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于POST请求及_api参数的Nginx限流配置问题

解决Nginx同时基于POST方法和POST参数_api的限流配置问题

我来帮你搞定这个Nginx限流的需求!你想要针对POST请求且请求体中包含_api参数的情况做限流,之前的尝试踩了几个常见的坑,我来一步步给你讲清楚正确的配置方式。

先分析你之前尝试的问题

  • $arg__api的配置:$arg_*系列变量只能获取URL中的GET参数,POST请求体里的参数根本不会被这个变量捕获,所以完全检测不到POST里的_api
  • 只判断POST方法的map配置:这个只能过滤请求方法,没法识别请求体里的参数,不符合你的双重条件要求。
  • 直接匹配$request_body"_api"的配置:POST请求体一般是键值对(比如_api=123&other=456)或者JSON格式(比如{"_api":"xxx"}),很少会是单纯的_api字符串,所以匹配不到;而且没结合请求方法判断,万一GET请求的URL里带了_api字符串,也会被错误限流。

正确的配置方案

要同时满足两个条件,我们需要把请求方法请求体内容结合起来判断,同时确保Nginx能正确读取到POST请求体的内容。下面是完整的配置示例:

# 1. 定义map,同时校验POST方法和请求体中是否包含_api参数
map $request_method$request_body $limit_trigger {
    # 正则匹配:POST方法 + 请求体中包含_api=(适配form-urlencoded格式的参数)
    ~*POST.*_api= $binary_remote_addr;
    # 如果是JSON格式的请求体,把上面的正则改成 ~*POST.*"_api"
    default "";
}

# 2. 定义限流区域,只有当$limit_trigger不为空时才会统计限流
limit_req_zone $limit_trigger zone=api_post_limit:10m rate=30r/m;

server {
    listen 80;
    server_name your_domain.com;

    # 关键配置:确保Nginx把POST请求体读到内存中,这样$request_body才能获取到内容
    client_body_buffer_size 128k;
    client_max_body_size 128k;

    location /your_target_path {
        # 应用限流规则
        limit_req zone=api_post_limit burst=10 nodelay;

        # 你的其他业务配置,比如反向代理到后端服务
        proxy_pass http://your_backend_service;
    }
}

配置原理说明

  • map的作用:把$request_method(请求方法)和$request_body(请求体内容)拼接成一个变量,用正则匹配是否同时满足「POST方法」和「请求体包含_api参数」。匹配成功时,用客户端IP($binary_remote_addr)作为限流的标识;否则返回空字符串,不会触发限流。
  • 请求体读取配置client_body_buffer_size设置足够大的内存缓冲区,让Nginx把POST请求体加载到内存里,这样$request_body才能拿到完整的请求体内容。如果请求体过大超过缓冲区,Nginx会把内容写到临时文件,此时$request_body会为空,就无法匹配参数了,所以要根据你的实际请求大小调整这个值。
  • 限流规则limit_req_zone使用$limit_trigger作为键,只有当这个变量不为空(也就是满足两个条件)时,才会进入限流统计,完美实现你的需求。

适配不同请求格式的调整

如果你的POST请求是JSON格式(比如{"_api": "test", "data": {}}),只需要把map里的正则改成:

~*POST.*"_api" $binary_remote_addr;

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

火山引擎 最新活动