nginx篇11-限速三剑客之limit_conn

本文最后更新于:July 8, 2021 pm

本文主要是对nginx官方limit_conn相关模块的配置用法和一些个人理解,limit_conn主要用于限制用户的连接数,在如今多线程并发请求大量普及的情况下,对于一些特殊的场景还是有着一定的用处的。

1、背景

目前来说在nginx上面我们常见的三种限速操作分别是:限制请求数(request)、限制连接数(connection)、限制响应速度(rate),对应在nginx的模块相关指令分别是limit_reqlimit_connlimit_rate三个系列。limit_conn模块和limit_req模块类似,有着许多个指令组成一个大的模块,两个模块之间有很多指令的命名方式和用法也大同小异,对limit_req模块有兴趣的可以点这里查看之前的文章

ngx_http_limit_conn_module 模块主要是用于根据特定的key来限制连接的数量,例如根据IP地址来限制连接数。需要注意的是并不是所有的连接都会被算入其中,只有当一个连接的整个请求头被读取并且已经被nginx服务器处理的时候才会算入限制中。这里我们重点介绍的还是limit_connlimit_conn_zone这两个指令。

2、limit_conn_zone指令

1
2
3
4
5
6
7
# 语法配置
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http

# 示例
limit_conn_zone $binary_remote_addr zone=addr:10m;
  • limit_conn_zone只能够在http块中使用

  • key就是用来判定连接数的变量,这个变量可以是文本、变量或它们的组合,例如我们可以使用IP地址+cookie等其他复杂的组合来更精确地限定范围

  • name就是这个zone的命名,经过实测name需要全局唯一,不可以和其他的limit_conn_zone的相同,毕竟后面的limit_conn命令需要根据这个name来查找对应的zone进行相应限制规则的匹配

  • size定义了这个zone的大小,也就是nginx会在内存中开辟多大的空间来存储这个zone的相关信息,主要和前面定义的key的大小有关系,需要注意的是,当内存大小耗尽的时候,nginx会直接返回错误码limit_conn_status给后续的请求

    If the zone storage is exhausted, the server will return the error to all further requests.

3、limit_conn指令

1
2
3
4
5
6
7
8
9
10
11
12
# 语法配置
Syntax: limit_conn zone number;
Default: —
Context: http, server, location

# 示例
limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
location /download/ {
limit_conn addr 1;
}
  • limit_conn能在httpserverlocation三个块中使用,但是需要注意的是要搭配前面提及的limit_conn_zone
  • limit_conn指令的变量只有zonenumber两个
  • 其中zone就是前面的limit_conn_zone中的name变量,也就是对应着全局唯一的zone,负责确定限制连接数的依据
  • 其中number就是限制的连接数,zone和number组合就可以完成连接数的限定功能,注意这里的number必须使用数字而不能使用变量

对于开启了HTTP2的请求来说,每个并发请求都会被当作一个单独的连接

In HTTP/2 and SPDY, each concurrent request is considered a separate connection.

4、其他指令

其他的一些指令用法相对简单,这里简单描述一下

4.1 limit_zone(已弃用)

1
2
3
Syntax:	limit_zone name $variable size;
Default: —
Context: http

生于1.1.8版本,卒于1.7.6版本

4.2 limit_conn_status

1
2
3
4
Syntax:	limit_conn_status code;
Default: limit_conn_status 503;
Context: http, server, location
This directive appeared in version 1.3.15.

limit_conn_status这个指令是用来指定nginx回复那些被禁用的连接请求时的状态码,默认情况下是503(Service Unavailable 服务不可用),如果是一些有特殊需求的场景,可以手动调整为403之类的状态码,需要注意的是并不是所有的状态码都可以使用,nginx官方限定状态码必须在400到599之间。

4.3 limit_conn_dry_run

1
2
3
4
Syntax:	limit_conn_dry_run on | off;
Default: limit_conn_dry_run off;
Context: http, server, location
This directive appeared in version 1.17.6.

dry_run模式的意义在于试运行而不对线上业务造成影响。设置为on之后,前面的limit_conn指令并不会真正生效,但是limit_conn_zone指令会生效,nginx会在内存中存储计算相关的数据。

4.4 limit_conn_log_level

1
2
3
4
Syntax:	limit_conn_log_level info | notice | warn | error;
Default: limit_conn_log_level error;
Context: http, server, location
This directive appeared in version 0.8.18.

用来调试的日志,从测试结果来看,会输出到error.log中而不是access.log,调成info的话会有较多的日志输出,需要额外注意硬盘容量等相关问题。