Nginx防止大流量攻击,限制流量访问(limit_req_zone模块)以及进行网站压力测试

本文详细解读了计数器、漏桶和令牌桶三种限流算法的工作原理,以及在Nginx配置中的limit_req_zone和limit_conn_module参数设置,还包括如何进行网站压力测试,如Webbench和ApacheBench的使用。

一、限流的几种算法

(一)、计数器算法

采用计数器实现限流有点简单粗暴,一般我们会限制一秒钟之内能够通过的请求数,比如限流 qps(每秒查询率)为100,算法的实现思路就是从第一个请求进来开始计时,在接下去的1s内,每来一个请求,就把计数加1,如果累加的数字达到了100,那么后续的请求就会被全部拒绝。等到1s结束后,把计数恢复成0,重新开始计数。
这种实现方式,有一个明显的弊端:如果在单位时间1s内的前10ms,已经通过了100个请求,那后面的990ms,只能眼巴巴的把请求拒绝,我们把这种现象称为“突刺现象”。

(二)、漏桶算法

为了消除"突刺现象",可以采用漏桶算法实现限流,漏桶算法这个名字就很形象,算法内部有一个容器,类似生活用到的漏斗,当请求进来时,相当于水倒入漏斗,然后从下端小口慢慢匀速的流出。不管上面流量多大,下面流出的速度始终保持不变。
不管服务调用方多么不稳定,通过漏桶算法进行限流,每10毫秒处理一次请求。因为处理的速度是固定的,请求进来的速度是未知的,可能突然进来很多请求,没来得及处理的请求就先放在桶里,既然是个桶,肯定是有容量上限,如果桶满了,那么新进来的请求就丢弃。

简单理解为:

  • 水(请求)从上方倒入水桶,从水桶下方流出(被处理);
  • 来不及流出的水存在水桶中(缓冲),以固定速率流出;
  • 水桶满后水溢出(丢弃)。
  • 这个算法的核心是:缓存请求、匀速处理、多余的请求直接丢弃。
  • 相比漏桶算法,令牌桶算法不同之处在于它不但有一只“桶”,还有个队列,这个桶是用来存放令牌的,队列才是用来存放请求的。

(三)、令牌桶算法

从某种意义上讲,令牌桶算法是对漏桶算法的一种改进,漏桶算法能够限制请求调用的速率,而令牌桶算法能够在限制调用的平均速率的同时还允许一定程度的突发调用。
在令牌桶算法中,存在一个桶,用来存放固定数量的令牌。算法中存在一种机制,以一定的速率往桶中放令牌。每次请求调用需要先获取令牌,只有拿到令牌,才有机会继续执行,否则就只能选择等待可用的令牌、或者直接拒绝。
放令牌这个动作是持续不断的进行,如果桶中令牌数达到上限,就丢弃令牌,所以就存在这种情况,桶中一直有大量的可用令牌,这时进来的请求就可以直接拿到令牌执行,比如设置 qps(每秒查询率)为100,那么限流器初始化完成一秒后,桶中就已经有100个令牌了,这时服务还没完全启动好,等启动完成对外提供服务时,该限流器可以抵挡瞬时的100个请求。所以,只有桶中没有令牌时,请求才会进行等待,最后相当于以一定的速率执行。

简单理解为:

  • 令牌以固定速率产生,并缓存到令牌桶中;
  • 令牌桶放满时,多余的令牌被丢弃;
  • 请求要消耗等比例的令牌才能被处理;
  • 令牌不够时,请求被缓存或者被拒绝

二、 limit_req_zone 参数配置

http {
   
   
    include       mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    #限流模块配置
     limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #
<think>我们正在处理一个关于Nginx配置错误的问题。用户报告的错误是“directive limit_req_zone is not terminated by semicolon”,这意味着在配置文件中,`limit_req_zone`指令没有以分号正确结束。 根据引用[1]和[2],我们知道`limit_req_zone`指令用于限制客户端的请求频率。它的基本语法结构如下: limit_req_zone key zone=name:size rate=rate; 常见的错误是在定义区域时忘记在行末添加分号,或者参数之间缺少必要的分隔符(如空格或分号)。 因此,我们需要检查配置文件中`limit_req_zone`指令的每一部分,确保: 1. 指令的每个参数之间用空格分隔。 2. 整个指令以分号(;)结束。 例如,一个正确的配置可能是: limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 注意:在`zone=one:10m`和`rate=1r/s`之间有一个空格,最后以分号结束。 另外,引用[3]和[4]提供了关于`limit_conn`模块的配置说明,虽然与`limit_req`模块不同,但配置指令的语法规则类似,都需要以分号结束。 因此,解决这个错误的方法是检查Nginx配置文件中使用`limit_req_zone`的语句,确保它正确结束(即最后有一个分号)。同时,检查指令中的各个参数是否正确(如key、zone名称、内存大小、速率等)。 如果用户提供了具体的配置行,我们可以帮助检查。但根据错误信息,最可能的原因就是缺少分号。 下面,我们按照用户要求的结构化方式来回答。</think>### Nginx 配置错误:`limit_req_zone` 指令未正确终止 **错误原因分析** 当出现 `directive "limit_req_zone" is not terminated by ";"` 错误时,根本原因是 `limit_req_zone` 指令的语法格式不正确,主要涉及两点: 1. **缺少结束分号**:指令末尾未用分号 `;` 终止 2. **参数分隔错误**:指令参数之间缺少必要的空格分隔符[^1][^2] --- ### 正确配置格式(对比示例) #### ❌ 错误写法(触发报错) ```nginx limit_req_zone $binary_remote_addr zone=rate_limit:10m rate=10r/s # 缺少分号 limit_req_zone$binary_remote_addr zone=rate_limit:10m rate=10r/s; # 参数间缺少空格 ``` #### ✅ 正确写法 ```nginx # 语法:limit_req_zone KEY zone=NAME:SIZE rate=RATE; limit_req_zone $binary_remote_addr zone=rate_limit:10m rate=10r/s; # 参数有空格 + 分号终止 ``` --- ### 关键参数说明 | 参数 | 作用 | 示例值 | |-----------------------|----------------------------------------------------------------------|----------------------| | `$binary_remote_addr` | 基于客户端IP限流(二进制格式更省内存) | 必填 | | `zone=name:size` | 定义共享内存区(`name`为区域名,`size`决定存储容量) | `zone=my_zone:10m` | | `rate=...` | 请求速率限制(`r/s`=每秒请求数,`r/m`=每分钟) | `rate=5r/s` | | `;` | **必须的终止符** | 指令末尾 | --- ### 完整配置示例 ```nginx http { # 步骤1:在http块定义限流规则 limit_req_zone $binary_remote_addr zone=api_limit:20m rate=100r/m; # ✅ 正确终止 server { listen 80; # 步骤2:在location应用限流 location /api/ { limit_req zone=api_limit burst=50 nodelay; # 突发请求处理 proxy_pass http://backend; } } } ``` --- ### 调试建议 1. **检查分号**:确保每个 `limit_req_zone` 指令末尾有 `;` 2. **验证空格**:确认参数间有空格分隔(特别是 `zone=` 和 `rate=` 前) 3. **测试配置**:运行 `nginx -t` 验证语法 ```bash nginx -t # 输出应显示 "syntax is ok" ``` 4. **内存容量**:确保 `zone` 的 `size` 值足够(如 `10m` 可存储约16万IP状态)[^3] > ⚠️ **注意**:此指令仅能在 `http` 上下文中使用,不可放入 `server` 或 `location` 块[^1][^3]。
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值