谈一谈nginx限制连接与请求的模块

前言

前段时间,所负责的项目疑似被爬虫爬取了;于是考虑从nginx层限制单IP访问频率;查阅相关资料后,发现nginx有两个相关的限制连接和请求的模块:ngx_http_limit_conn_module,ngx_http_limit_req_module;接下来就简单谈一谈这两个模块;

寻根溯源

ngx_http_limit_conn_module

我们先看看,官网http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
如何介绍ngx_http_limit_conn_module模块的,以下为简单翻译:

  • 配置示例
  • 指令
    limit_conn
    limit_conn_dry_run
    limit_conn_log_level
    limit_conn_status
    limit_conn_zone
    limit_zone
  • 嵌入式变量
配置示例
http {
    limit_conn_zone $binary_remote_addr zone=addr:10m;

    ...

    server {

        ...

        location /download/ {
            limit_conn addr 1;
        }
指令集

limit_conn

语法: limit_conn zone number;
默认值:    —
作用域:    http, server, location

设置共享内存区域和给定键值的最大允许连接数。当超过此限制时,服务器将返回错误以回复请求。例如,指令

limit_conn_zone $binary_remote_addr zone=addr:10m;

server {
    location /download/ {
        limit_conn addr 1;
    }

每个IP地址只允许一个连接。
HTTP/2SPDY中,每个并发请求都被视为一个单独的连接。
可能有多个limit_conn指令。例如,以下配置将限制每个客户端IP与服务器的连接数,并同时限制与虚拟服务器的连接总数:

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

当且仅当当前级别上没有limit_conn指令时,这些指令才从上一级继承。

limit_conn_dry_run

语法:limit_conn_dry_run on | off;
默认值:limit_conn_dry_run off;
作用域:http, server, location
该指令出现在版本1.17.6中

启用空运行模式。在此模式下,连接数不受限制,但是,在共享内存区域中,过多连接的数将照常计算。

limit_conn_log_level

语法:limit_conn_log_level info | notice | warn | error;
默认值:limit_conn_log_level error;
作用域:http, server, location
该指令出现在版本 0.8.18中.

为服务器限制连接数的情况设置所需的日志记录级别。

limit_conn_status

语法:limit_conn_status code;
默认值:limit_conn_status 503;
作用域:http, server, location
该指令出现在版本1.3.15中.

设置状态代码以响应被拒绝的请求。

limit_conn_zone

语法:limit_conn_zone key zone=name:size;
默认值:    —
作用域:http

设置共享内存区域的参数,该参数将保留各种键的状态;特别是,状态包括当前的连接数。键可以包含文本,变量及其组合。键为空的请求不予考虑。
在版本1.7.6之前,键可以只包含一个变量。
用法示例:

limit_conn_zone $binary_remote_addr zone=addr:10m;

在这,客户端的一个IP地址作为一个key,请注意,此处使用$binary_remote_addr变量代替$remote_addr$remote_addr变量的大小可以从7到15个字节不等。 存储状态在32位平台上占用32或64字节的内存,在64位平台上始终占用64字节。 $binary_remote_addr变量的大小对于IPv4地址始终为4个字节,对于IPv6地址始终为16个字节。 在32位平台上,存储状态始终占据32或64字节,在64位平台上,存储状态始终占据64字节。 1M的区域可以保留大约3.2万个32字节状态或大约1.6万个64字节状态。 如果区域存储空间已用完,服务器将把错误返回给所有其他请求。

此外,作为我们的商业订阅的一部分,可以从1.17.7开始使用API​​获取或重置每个此类共享存储区的状态信息

limit_zone

语法:limit_zone name $variable size;
默认值:—
作用域:http

该指令在1.1.8版中已过时,在1.7.6版中已删除。应当使用等效的limit_conn_zone伪指令(其语法已更改)代替:

limit_conn_zone $variable zone=name:size;

嵌入式变量

$limit_conn_status
保留限制连接数(1.17.6)的结果:PASSED,REJECTED或REJECTED_DRY_RUN

ngx_http_limit_req_module

我们继续看看官网 http://nginx.org/en/docs/http/ngx_http_limit_req_module.html
是如何介绍ngx_http_limit_conn_module模块的,以下为简单翻译:

  • 配置示例
  • 指令
    limit_req
    limit_req_dry_run
    limit_req_log_level
    limit_req_status
    limit_req_zone
  • 嵌入式变量
    ngx_http_limit_req_module模块(0.7.21)用于限制每个已定义key的请求处理速率,特别是来自单个IP地址的请求的处理速率。使用“漏斗”方法完成限制。

配置示例

http {
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

    ...

    server {

        ...

        location /search/ {
            limit_req zone=one burst=5;
        }

指令集

limit_req

语法:limit_req zone=name [burst=number] [nodelay | delay=number];
默认值:—
作用域:http, server, location

设置共享内存区域和请求的最大突发大小。 如果请求速率超过为区域配置的速率,则会延迟其处理,以便以定义的速率处理请求。 过多的请求将被延迟,直到其数量超过最大突发大小为止,在这种情况下,该请求将因错误而终止。 默认情况下,最大突发大小等于零。 例如,指令

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

server {
    location /search/ {
        limit_req zone=one burst=5;
    }

平均每秒最多允许不超过1个请求,并且突发不超过5个请求
如果不需要在限制请求时延迟过多的请求,则应使用参数nodelay

limit_req zone=one burst=5 nodelay;

delay参数(1.15.7)指定一个限制,在该限制下,过多的请求将被延迟。默认值为零,即所有多余的请求都会延迟。
可能有多个limit_req指令。例如,以下配置将限制来自单个IP地址的请求的处理速度,同时限制虚拟服务器的请求处理速度:

limit_req_zone $binary_remote_addr zone=perip:10m rate=1r/s;
limit_req_zone $server_name zone=perserver:10m rate=10r/s;

server {
    ...
    limit_req zone=perip burst=5 nodelay;
    limit_req zone=perserver burst=10;
}

当且仅当当前级别上没有limit_req指令时,这些指令才从上一级继承

limit_req_dry_run

语法:limit_req_dry_run on | off;
默认值:limit_req_dry_run off;
作用域:http, server, location
该指令出现在1.17.1版中

启用空运行模式。在这种模式下,请求处理速度不受限制,但是,在共享内存区域中,过多请求的数量将照常进行计算。

limit_req_log_level

语法:limit_req_log_level info | notice | warn | error;
默认值:limit_req_log_level error;
作用域:http, server, location
该指令出现在0.8.18版中.

在服务器由于速率超出而拒绝处理请求或延迟请求处理的情况下,设置所需的日志记录级别。延迟的日志级别比拒绝低了一个等级,例如,如果指定了日志级别为 limit_req loglevel notice,延迟的日志级别为info

limit_req_status

语法:limit_req_status code;
默认值:limit_req_status 503;   
作用域:http, server, location
该指令出现在1.3.15版中.

设置状态代码以响应被拒绝的请求

limit_req_zone

语法:limit_req_zone key zone=name:size rate=rate [sync];
默认值:—
作用域:http

设置共享内存区域的参数,该参数将保留各种键的状态。 特别是,状态存储了当前过多请求的数量。 键可以包含文本,变量及其组合。 key值为空的请求不予考虑。
在版本1.7.6之前,键可以只包含一个变量
用法示例:

limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

这里,状态保持在10M的区域one中,并且该区域的平均请求处理速率不能超过每秒1个请求。
客户端IP地址用作密钥。 请注意,此处使用$binary_remote_addr变量代替$remote_addr$binary_remote_addr变量的大小对于IPv4地址始终为4个字节,对于IPv6地址始终为16个字节。 存储状态在32位平台上始终占据64字节,在64位平台上始终占据128字节。 一个1M字节的区域可以保留约1.6万个64字节状态或约8000个128字节状态。
如果区域存储已用尽,则删除最近最少使用的状态。如果在此之后仍无法创建新状态,则请求将终止并出现错误
该速率以每秒请求数r/s指定。如果希望速率小于每秒一个请求,则以每分钟请求数r/m来指定。例如,每秒半请求为30r/m
sync参数(1.15.3)启用共享内存区域的同步

嵌入式变量

$limit_req_status
保留限制请求处理速率(1.17.6)的结果:PASSED,DELAYED,REJECTED,DELAYED_DRY_RUN或REJECTED_DRY_RUN

小结

简单来说,如果想要比较准确的限制爬虫等非法请求,尽量两个模块结合使用

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358