配置 Nginx 限流一共包含哪些部分?使用场景是什么?底层原理是什么?
·
1. 配置 Nginx 限流包含哪些部分?
核心比喻:像“幼儿园门卫”一样控制入园人数
- 问题:
如果很多小朋友突然挤进幼儿园(大量请求),门卫无法管理,教室会被挤垮! - 核心组成部分:
- 全局限流配置:定义限流规则(如每秒最多10次请求)。
- 速率限制模块:
limit_req控制请求速率。 - 连接数限制模块:
limit_conn控制同时连接数。 - 共享内存区域:存储IP的请求计数。
- 错误处理:超过限制时返回503错误。
2. 使用场景
- 高流量网站:
如电商大促时,防止服务器被压垮。 - API接口:
限制第三方调用频率(如每秒最多10次)。 - 防止恶意爬虫:
拦截频繁访问的爬虫(如每秒超过50次请求)。 - 资源保护:
限制核心接口的并发连接数(如支付接口)。
3. 底层原理
(1) 如何限流?
limit_req模块:- 令牌桶算法:
每秒生成固定数量的“令牌”,请求需要先获取令牌才能进入。rate=10r/s:每秒生成10个令牌。burst=20:允许突发20次请求(但平均速率不能超过10r/s)。
- 令牌桶算法:
limit_conn模块:- 控制单个IP的并发连接数(如同时最多允许5个连接)。
- 共享内存区域:
- Nginx用内存记录每个IP的请求次数和连接数,速度快且高效。
(2) 核心机制
- 全局配置:
在http块中定义共享内存区域(如limit_req_zone)。 - 局部应用:
在server或location块中引用配置(如limit_req zone=one)。 - 动态调整:
通过参数burst和nodelay控制突发流量和延迟策略。
4. 流程图
以下是 Nginx 限流的流程:
+-------------------+
| 用户发送请求 | (如访问商品页面)
+-------------------+
|
v
+-------------------+
| Nginx检查限流规则 | (如每秒最多10次请求)
+-------------------+
|
v
+-------------------+
| 判断是否超限 | (是 → 返回503;否 → 继续处理)
+-------------------+
|
v
+-------------------+
| 返回结果给用户 | (合法请求正常处理)
+-------------------+
5. 概念图
以下是 Nginx 限流的核心概念:
+-------------------+
| Nginx限流配置 |
+-------------------+
|
v
+-------------------+
| 共享内存区域 | (存储IP的计数)
+-------------------+
|
v
+-------------------+
| 速率限制模块 | (limit_req 控制请求速率)
+-------------------+
|
v
+-------------------+
| 连接数限制模块 | (limit_conn 控制并发连接)
+-------------------+
|
v
+-------------------+
| 错误响应 | (返回503 Too Many Requests)
+-------------------+
6. UML 类图
以下是简化后的 UML 类图(用配置块表示):
+-------------------+
| Nginx配置 |
+-------------------+
| - http块 | (全局配置区域)
| - server块 | (虚拟主机配置)
| - location块 | (路径级配置)
+-------------------+
+-------------------+
| limit_req_zone |
+-------------------+
| - key: string | (如 $binary_remote_addr)
| - rate: string | (如 10r/s)
| - zone: string | (共享内存区域名称和大小)
+-------------------+
+-------------------+
| limit_req |
+-------------------+
| - zone: string | (引用共享内存区域)
| - burst: int | (突发请求数)
| - nodelay: bool | (是否允许直接使用突发令牌)
+-------------------+
7. 思维导图
以下是 Nginx 限流的思维导图:
+-------------------+
| Nginx限流配置 |
+-------------------+
| + 核心模块 |
| + limit_req |
| + limit_conn |
| + 共享内存区域 |
| + key |
| + rate |
| + zone |
| + 参数说明 |
| + burst |
| + nodelay |
| + 使用场景 |
| + 防止DDoS |
| + API限流 |
+-------------------+
8. 实例代码(Nginx 配置示例)
以下是完整的 Nginx 配置文件示例:
# 1. 全局配置:定义共享内存区域
http {
# 定义速率限制区域(limit_req_zone)
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; # (a) 每秒最多10次请求
limit_req_zone $server_name zone=per_server:10m rate=100r/s; # (b) 每个虚拟主机每秒最多100次请求
# 定义连接数限制区域(limit_conn_zone)
limit_conn_zone $binary_remote_addr zone=addr_conn:10m; # (c) 按IP限制连接数
limit_conn_zone $server_name zone=per_server_conn:10m; # (d) 按服务器名称限制连接数
}
server {
listen 80;
server_name example.com;
# 2. 应用限流到特定路径(如API接口)
location /api/ {
# 应用速率限制
limit_req zone=one burst=20 nodelay=on; # (e) 允许突发20次请求,且立即使用令牌
# 应用连接数限制
limit_conn addr_conn 5; # (f) 同一IP最多5个并发连接
# 其他配置(如代理到PHP)
proxy_pass http://backend;
}
# 3. 全局限流(所有请求)
limit_req zone=per_server burst=100 nodelay=off; # (g) 每个服务器每秒最多100次请求,突发100次需排队
limit_conn per_server_conn 100; # (h) 每个服务器最多100个并发连接
# 4. 错误页面配置
error_page 503 /503.html; # (i) 超限时显示自定义页面
location = /503.html {
internal;
root /var/www/html;
}
}
代码注释详细解释
第 1 步:定义共享内存区域
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;
- 作用:定义一个名为
one的共享内存区域,存储IP的请求计数。 - 为什么这么写:
$binary_remote_addr是IP的二进制形式,节省内存。10m是内存大小(10MB,可存储约6万个IP计数)。
- 知识点:Nginx 的
limit_req_zone配置语法。
第 2 步:引用限流规则
limit_req zone=one burst=20 nodelay=on;
- 作用:在
/api/路径应用one区域的限流规则。 - 为什么这么写:
burst=20:允许突发20次请求。nodelay=on:突发请求立即处理,无需排队。
- 知识点:
limit_req模块参数。
第 3 步:连接数限制
limit_conn addr_conn 5;
- 作用:限制同一IP的并发连接数为5。
- 为什么这么写:防止单IP占用过多服务器资源。
- 知识点:
limit_conn模块的使用。
第 4 步:错误页面配置
error_page 503 /503.html;
- 作用:当请求被限流时,显示自定义的503页面。
- 为什么这么写:提升用户体验,避免直接看到Nginx默认错误页。
- 知识点:Nginx 的错误页面重定向。
9. 详细说明
(1) 速率限制参数
rate=10r/s:
每秒生成10个令牌,每个请求消耗1个令牌。burst=20:
允许在短时间内超过速率,但总请求不能超过速率+突发值。- 示例:1秒内允许30次请求(10r/s × 1秒 + 20突发)。
nodelay:on:突发请求直接使用令牌,无需排队。off:突发请求需排队等待。
(2) 共享内存区域
zone=one:10m:one:区域名称。10m:内存大小,存储更多IP的计数。
(3) 连接数限制
limit_conn addr_conn 5:
同一IP同时最多5个连接,超过则拒绝。
10. 总结
- Nginx限流是“幼儿园门卫系统”:
limit_req:控制小朋友进入速度(每秒最多10个)。limit_conn:控制滑梯区同时只能有5个小朋友。
- 核心步骤:
- 在
http块定义共享内存区域。 - 在
server或location块应用限流规则。
- 在
- 底层原理:
通过令牌桶算法和共享内存计数,动态控制请求速率和并发连接数。
11. 扩展问题解答
Q1: 为什么用 binary_remote_addr 而不是 remote_addr?
- A1:二进制IP地址更节省内存(存储空间减少)。
Q2: 如何测试限流是否生效?
- A2:
- 使用
ab工具模拟高并发请求:ab -n 100 -c 10 http://example.com/api/ - 观察是否返回503错误。
- 使用
Q3: 如何限制特定路径?
- A3:在
location块中单独配置限流规则(如示例中的/api/)。
12. 完整配置示例(含注释)
# 1. 定义全局限流区域
http {
# 速率限制:按IP限制,每秒最多10次,存储在10MB内存中
limit_req_zone $binary_remote_addr zone=ip_rate_limit:10m rate=10r/s; # (a) 定义IP限流区域
# 连接数限制:按IP限制,最多5个并发连接
limit_conn_zone $binary_remote_addr zone=ip_conn_limit:10m; # (b) 定义连接数区域
server {
listen 80;
server_name myapp.com;
# 2. 应用限流到特定路径(如API)
location /api/ {
# 应用IP速率限制
limit_req zone=ip_rate_limit burst=20 nodelay=on; # (c) 允许突发20次请求
# 应用连接数限制
limit_conn ip_conn_limit 5; # (d) 同一IP最多5个并发连接
# 其他配置(如反向代理)
proxy_pass http://backend;
}
# 3. 全局限流(所有请求)
limit_req zone=ip_rate_limit burst=30 nodelay=off; # (e) 全局速率限制,突发需排队
# 4. 连接数全局限制(整个服务器)
limit_conn ip_conn_limit 100; # (f) 服务器最多100个并发连接
# 5. 错误页面配置
error_page 503 /custom_503.html;
location = /custom_503.html {
root /var/www/html;
internal;
}
}
}
13. 总结
- Nginx限流是“幼儿园的门卫规则”:
- 通过
limit_req控制进入速度。 - 通过
limit_conn控制同时人数。
- 通过
- 核心作用:
防止服务器被恶意请求压垮,保护资源。 - 底层原理:
使用共享内存存储计数,结合令牌桶算法动态控制流量。
14. 关键知识点总结
| 指令 | 作用 | 示例 |
|---|---|---|
limit_req_zone | 定义速率限制区域 | 控制IP每秒请求次数 |
limit_req | 应用速率限制到路径或服务器 | 在 /api/ 限流 |
limit_conn_zone | 定义连接数限制区域 | 按IP限制并发连接数 |
limit_conn | 应用连接数限制到路径或服务器 | 同一IP最多5个连接 |
burst | 允许的突发请求量 | burst=20 允许突发20次 |
nodelay | 是否立即处理突发请求 | on → 直接处理 |
15. 总结
- 配置 Nginx 限流是“设置幼儿园规则”:
- 通过
limit_req控制请求速度,limit_conn控制同时人数。
- 通过
- 核心步骤:
- 定义共享内存区域。
- 在路径或服务器上应用限流规则。
- 配置错误页面提升体验。
- 底层原理:
令牌桶算法和共享内存计数,动态控制流量。
更多推荐



所有评论(0)