> For the complete documentation index, see [llms.txt](https://yangsx95.gitbook.io/notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yangsx95.gitbook.io/notes/distributed/web-fu-wu-qi/nginx/qing-qiu-xian-zhi.md).

# 请求限制

* `limit_conn_module` 连接频率限制
* `limit_req_module` 请求频率限制

**连接和请求的区别？**

每个http请求至少会建立一次TCP连接，而一次TCP连接至少会产生一次HTTP请求。在不同版本的HTTP协议，针对连接的复用有不同的标准：

| HTTP协议版本 | 连接关系                      |
| -------- | ------------------------- |
| HTTP1.0  | TCP不可服用，每次HTTP都要建立一次TCP连接 |
| HTTP1.1  | 顺序性TCP复用                  |
| HTTP2.0  | 多路复用TCP复用                 |

## http\_limit\_conn\_module

连接限制配置：

```nginx
# 申请存储空间zone
# 如果要对连接进行限制，那么就要存储连接的信息，记录连接的状态
# 那么就需要将在操作系统中申请一块空间，即 limit_conn_zone；
# 指定存储的key，比如以 $remote_addr 作为key， 那么就会对 客户端的ip进行限制
# zone=name 指定zone的名字
# size用来指定空间的大小
Syntax: limit_conn_zone key zone=name:size;
Default:
Context:http


# 对zone进行限制，使用number限定连接个数
# 此配置依赖zone配置
Syntax: limit_conn_zone number;
Default: 
Context: http, server, location
```

## http\_limit\_req\_moudle

```nginx
# 定义zone，key代表限制的目标，size代表空间大小，rate指定速率
Syntax: limit_req_zone key zone=name:size rate=rate
Default: 
Context: http

# 对zone进行限制，name指定zone, burst=number是指当请求爆满无法处理时，让其中number等待到下一秒处理。 nodelay意为不等待，立即返回503，否则会超时
Syntax: limit_req zone=name [burst=number] [nodelay]
Default: 
Context: http, server, location
```

## 示例

```nginx
# 定义连接限制zone
limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
# 定义请求限制zone，限制同一个客户端每秒只允许请求一次
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;

location / {
    root /usr/share/nginx/html;
    #limit_conn conn_zone 1;
    #limit_req zone=req_zone burst=3 nodelay;
    #limit_req zone=req_zone burst=3;
    #limit_req zone=req_zone;
}

# 依次单独打开上面的注释，然后使用ab命令进行压力测试，观察请求成功和失败的数量 
# -n 总共发送20个请求
# -c 并发请求数为20
ab -n 20 -c 20 http://localhost/
```

> ab 命令的使用请查看其他文章。

执行结果分析：

```
# 1. limit_req zone=req_zone;
总共发送20个请求，其中19个都是非两百的请求

# 2. limit_req zone=req_zone burst=3 nodelay;
总共发送20个请求，其中16个都是非200的请求，因为有三个被演示处理了

# 3. limit_conn conn_zone 1;
总共发送20个请求，其中有三个非200的请求，虽然限制了连接数为一，但是一个连接可以处理多个请求，所以只有三个未成功
```
