五分钟学Nginx 限速原理与配置

Nginx是一款高性能的开源Web服务器和反向代理服务器,它提供了丰富的功能和模块,其中包括一些用于限制请求、连接和响应速度的功能,以帮助管理员更好地管理服务器资源和应对潜在的攻击。在本文中,我们将详细介绍Nginx的三种限速操作以及它们对应的模块指令:限制请求数(limit_req)、限制连接数(limit_conn)和限制响应速度(limit_rate)。

image.png

限制请求数(limit_req)

    Nginx的limit_req模块用于限制客户端对服务器的请求速率,以防止服务器过载或恶意攻击。这个模块允许你设置每个客户端可以发送的请求数的上限。

limit_req模块的工作原理

    limit_req模块基于令牌桶算法来限制请求速率。它会为每个客户端IP地址维护一个令牌桶,每个令牌代表一个可以被处理的请求。令牌桶以一定的速率(例如每秒N个令牌)填充。当一个请求到达时,会尝试从令牌桶中获取一个令牌。如果令牌桶中没有足够的令牌,请求就会被延迟或拒绝,直到有足够的令牌为止。

limit_req配置示例

    以下是一个具体的场景和相应的Nginx配置,用于限制请求速率。假设你的网站每秒最多只能处理10个请求,超过这个速率的请求将被延迟或拒绝。

代码语言:javascript
复制
http {
    # 定义请求速率限制区域,将客户端IP地址映射到一个区域中
    limit_req_zone $binary_remote_addr zone=limit_per_ip:10m rate=10r/s;
    server {
        listen 80;
        server_name yourwebsite.com;
        location / {
            # 启用请求速率限制,引用之前定义的区域
            limit_req zone=limit_per_ip burst=20;
            # 其他配置项,例如代理请求到后端应用程序
        }
    }
}

定义速率限制参数

代码语言:javascript
复制
Syntax:limit_req_zone key zone=name:size rate=rate [sync];
Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];

    首先,我们使用limit_req_zone指令定义了一个速率限制区域(zone)。这个区域用于存储客户端IP地址的请求计数信息,以及限制请求的速率。以下是相关参数的说明:

  • key:用于限制请求的变量。在这个示例中,我们使用了Nginx内置变量$binary_remote_addr,该变量以二进制形式表示客户端的IP地址。这种表示方式相比$remote_addr(以文本形式表示IP地址)更加节省内存。使用$binary_remote_addr则意味着将每个唯一的用户IP作为限制速率的判断依据。
  • zone:定义了共享内存区域的名称和大小。将信息存储在共享内存中的好处在于多个Nginx worker进程可以共享这些信息。区域的定义包括区域名称和大小,例如zone=limit_per_ip:10m表示一个名为limit_per_ip、大小为10MB的共享内存区域。当存储空间耗尽的时候,如果需要记录新的值,那么就会通过LRU算法移除旧的变量来腾出空间,如果这样腾出来的空间还是不足以接纳新的记录值,那么nginx就会返回状态码503``(Service``Temporarily``Unavailable)。此外,为了防止内存耗尽,nginx每次创建一个新记录值的时候就会清理掉两个60秒内没被使用过的旧记录值。
  • rate:指定允许的最大请求速率。在本例中,我们设置为每秒允许10个请求(10r/s)。Nginx以毫秒级别的粒度来控制请求速率,因此10r/s实际上是1r/100ms,这意味着如果在前一个请求处理后的100毫秒内出现第二个请求,它将被拒绝处理。

启用限速

接下来,我们在Nginx配置中的特定location块中使用limit_req指令来启用上述定义的限速参数。在此示例中,我们将请求速率限制应用于/路径

请注意,limit_req模块非常有用,特别是在防止DDoS攻击或恶意请求时,可以帮助我们保护服务器的稳定性和可用性。根据我们的实际需求,可以根据具体情况调整速率限制参数以适应不同的流量情况。

 对于limit_req 还有更高级的一些用法,推荐阅读nginx 官方的这篇博文:https://www.nginx.com/blog/rate-limiting-nginx/

限制连接数(limit_conn)

限制连接数(limit_conn)是一种用于管理客户端与服务器之间的连接数量的方法,目的是防止服务器过载或遭受滥用攻击。在Nginx中,我们可以使用limit_conn模块来实现这种连接数限制。下面将详细介绍如何配置和工作原理。

配置limit_conn模块

代码语言:javascript
复制
http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;
    server {
        location / {
            limit_conn addr 10;
            # 其他配置
        }
    }
}
  1. limit_conn_zone指令用于定义连接数限制的区域。这个指令将客户端的IP地址映射到一个特定的区域,并设置了该区域的最大连接数。在上面的示例中,我们创建了一个名为addr的区域,最大连接数为10。这意味着每个不同的客户端IP地址最多可以建立10个连接。
  2. limit_conn指令用于在特定的location块内启用连接数限制。它引用了之前定义的addr区域,并设置了允许的最大连接数。在这个示例中,允许的最大连接数为10。

工作原理

现在让我们深入了解limit_conn模块的工作原理:

  1. 当一个客户端请求到达Nginx服务器时,Nginx会提取客户端的IP地址(通常是$binary_remote_addr)。
  2. Nginx将客户端的IP地址与之前定义的limit_conn_zone区域进行匹配。如果在该区域中没有找到客户端IP地址的条目,Nginx会创建一个新的条目,并将该IP地址与连接数计数器关联。
  3. 如果连接数计数器小于或等于允许的最大连接数(在这个示例中是10),Nginx将允许该连接继续处理。否则,Nginx将拒绝该连接并返回适当的错误响应给客户端。
  4. 当连接完成或被关闭时,Nginx会减少与该连接关联的连接数计数器。

这样,通过使用limit_conn模块,Nginx可以有效地控制每个客户端IP地址可以建立的连接数量,从而保护服务器免受连接数过多的威胁,确保服务器资源得以合理利用。

总结起来,limit_conn模块允许您配置服务器上允许的最大连接数,并根据客户端的IP地址对连接进行计数和限制。这有助于维护服务器的稳定性和安全性,特别是在面对连接数过多的情况下。

限制响应速度(limit_rate)

限制响应速度(limit_rate)是一种用于控制服务器向客户端发送响应数据的速率的方法。这可以帮助防止网络拥塞、提高服务质量,以及防止恶意下载导致服务器资源过度消耗。在Nginx中,可以使用limit_rate指令来实现这种响应速率限制。

配置limit_rate指令

代码语言:javascript
复制
http {
    server {
        location / {
            limit_rate 100k;
            # 其他配置
        }
    }
}

    limit_rate指令用于在location`块内设置响应速率限制。在上面的示例中,我们将响应速率限制为每秒100KB。这意味着服务器将以每秒100KB的速率向客户端发送响应数据。

工作原理

深入了解limit_rate指令的工作原理:

  1. 当客户端发起一个请求并Nginx开始响应时,Nginx会检查请求对应的location块中是否有设置了limit_rate指令。
  2. 如果有设置limit_rate指令,Nginx会根据指定的速率限制向客户端发送响应数据。在上面的示例中,限制为每秒100KB。
  3. Nginx会定期检查已发送的数据量,以确保不超过指定的速率限制。如果发送速率超过了限制,Nginx会暂停发送数据,直到速率再次在允许范围内。
  4. 当响应数据完全发送给客户端或连接关闭时,速率限制将不再适用。

通过这种方式,Nginx可以控制响应数据的发送速率,确保服务器资源合理利用,防止过快的数据传输,以及降低网络拥塞的风险。

limit_rate指令是Nginx提供的用于控制响应速率的功能,它通过限制服务器向客户端发送响应数据的速率,有助于维持服务器的稳定性、防止过度消耗带宽、提高服务质量,并对恶意下载行为进行限制。通过合理配置limit_rate,管理员可以更好地管理服务器资源,确保服务器正常运行。这与其他Nginx限速功能,如限制请求数(limit_req)和限制连接数(limit_conn)结合使用,可以提高服务器的安全性和性能。

可以查看原文:

https://mp.weixin.qq.com/s?__biz=MzA5NTgwNzY1NA==&mid=2247484060&idx=2&sn=42b3408a9853de324c5f0bbf8d5a3f58&chksm=90b8f355a7cf7a432f36ba7ad150b514c2e4f5f3a8dc6e23585b38652d3c1b5e897600c4c6be&token=211557010&lang=zh_CN#rd