文章目录
- 前言
- 一、Nginx限流
- 1、简介
- 2、关于 limit_req 和 limit_conn 的区别
- 3、limit_conn 模块
- (1)limit_conn_zone
- (2)limit_conn
- (3)limit_conn_log_level
- (4)limit_conn_status code
- (5)limit_rate
- (6)limit_rate_after
- (7)实例
- 4、limit_req 模块
- (1)流量控制的概念
- (1)limit_req_zone
- (2)limit_req
- (3)实例
- 5、处理突发
- (1)为什么要使用burst
- (2)实例
- 6、配置流量控制相关功能
- (1)配置日志记录
- (2)发送到客户端的错误代码
- 二、访问控制
- 1、Nginx访问控制模块类型
- 2、基于IP模块
- 3、location拒绝所有请求
- 4、用户的信任登录
前言
一、Nginx限流
1、简介
主要是当访问量达到一个限制量的时候可以选择以服务器为主要,而选择对用户访问请求的量做限制,对于超出限制的用户请求会采取丢弃或者延迟处理等方式处理,来保证更多用户来访问处理。
比如:某一服务器正常在高峰期上能支持的访问量是1w,但是突然某一时刻在访问量上突然暴增一下子超过3w,5w则可能会导致服务器宕机,这个时候我们 就可以通过设置最大的访问如1分钟访问8000次。
也可以防止攻击(对同一个ip每秒访问多少次)如:30min/次。
对应模块
- limit_conn_module 限制连接数
- limit_req_module 限制请求频率
2、关于 limit_req 和 limit_conn 的区别
limit_req
和limit_conn
两个模块都是为了来限流的,但是两者不在一个层面,为了搞清楚这个,必须先要弄清楚request
和connection
的区别,因为在很多情况下,我们把他们混淆了。
- connection是连接,即常说的tcp连接,通过三次握手而建立的一个完整状态机。建立一个连接,必须得要三次握手。
- request是指请求,即http请求,(注意,tcp连接是有状态的,而构建在tcp之上的http却是无状态的协议)。
通过打开一个网页,然后通过wireshark可以看到,一个连接建立后(即三次握手后),在这个连接断开之前(即四次挥手之前),会有很多的 http request,
这就是它们的区别:即一个连接的生命周期中,会存在一个或者多个请求,这是为了加快效率,避免每次请求都要三次握手建立连接,现在的HTTP/1.1协议都支持这种特性,称为长连接(keepalive)。
3、limit_conn 模块
通过 limit_zone 模块来达到限制用户的连接数的目的,即限制同一用户 IP 地址的并发连接数。
对于提供下载的网站,肯定是要进行流量控制的。Nginx 通过 core模块的 limit_rate 等指令可以做到限流的目的。
(1)limit_conn_zone
语法:limit_conn_zone key zone=name:size;
默认:no
区域:http
功能:该指令定义一个 zone,该 zone 存储会话的状态。
说明:
- key 是 Nginx 中的变量,通常为 binaryremoteaddr|server_name;
- name 为共享内存的名称,size 为该共享内存的大小;此配置会申请一块共享内存空间 name,并且保存 key 的访问情况。
(2)limit_conn
语法:limit_conn zone_name number
配置上下文:http,server,location
说明:
- 使用 zone_name 进行访问并发控制,当超过 number 时返回对应的错误码
(3)limit_conn_log_level
语法:limit_conn_log_level info|notice|warn|error
默认值:error
配置上下文:http,server,location
说明:
- 当访问达到最大限制之后,会将访问情况记录在日志中
(4)limit_conn_status code
语法:limit_conn_status code
默认值:503
配置上下文:http,server,location
说明:
- 当访问超过限制 number 时,给客户端返回的错误码,此错误码可以配合 error_page 等参数,在访问超量时给客户返回友好的错误页面
(5)limit_rate
语法:limit_rate speed;
默认值:no
使用环境:http、server、location
示例: limit_rate 512k;
说明:
- 对每个链接的速率进行限制,rate 表示每秒的下载速度;
(6)limit_rate_after
语法:limit_rate_after size;
默认值:limit_rate_after 1m;
使用环境:http、server、location
示例:limit_rate_after 3m;
说明:
- 此命令和 limit_rate 配合,当流量超过 size 之后,limit_rate 才开始生效
(7)实例
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
listen 80;
server_name www.domain.com;
root /path/;
index index.html index.htm;
location /ip {
limit_conn_status 503; # 超限制后返回的状态码;
limit_conn_log_level warn; # 日志记录级别
limit_rate 50; # 带宽限制
limit_conn addr 1; # 控制并发访问
}
# 当超过并发访问限制时,返回503错误页面
error_page 503 /503.html;
}
4、limit_req 模块
使用 ngx_http_limit_req_module 模块可以 限制某一 IP 在一段时间内对服务器发起请求的连接数,该模块为用来做流量控制。
(1)流量控制的概念
流量限制 (rate-limiting),它可以用来限制客户端在指定时间内 HTTP 请求的数量。请求可以是GET 请求,也可以是登录表单的 POST 请求。
流量限制可以用作安全目的,如减慢暴力密码破解速率等。通过将传入请求的速率限制为真实用户的典型值,并标识目标 URL 地址(通过日志),还可以用来抵御 DDOS 攻击,该功能可以用来保护上游应用服务器不被同时太多用户请求所压垮。
Nginx 流量限制使用漏桶算法(leaky bucket algorithm),漏桶算法在通讯和分组交换计算机网络中广泛使用,用于处理带宽有限时的突发情况。
-
limit_req_zone
指令定义了流量限制相关的参数 -
limit_req
指令在出现的上下文中启用流量限制。
该模块主要控制单位时间内的请求数。使用 “leaky bucket” (漏斗)算法进行过滤,在设置好限制 rate 之后,当单位时间内请求数超过 rate 时,模块会检测 burst 值,如果值为0,则请求会依据 delay|nodelay 配置返回错误或者进行等待;如果 burst 大于0时,当请求数大于 rate 但小于 burst 时,请求进入等待队列进行处理。
(1)limit_req_zone
语法:limit_req_zone key zone=name:size rate=rate
配置上下文:http
说明:
- key 是 Nginx 中的变量,通常为
binary_remote_addr
|server_name
; - name 为共享内存的名称,size 为该共享内存的大小;
- rate 为访问频率,单位为 r/s 、r/m 。此配置会申请一块共享内存空间 name,并且保存 $key 的访问情况;
(2)limit_req
语法: limit_rate zone=name [burst=number] [nodelay|delay=number]
配置上下文:http,server,location
说明:
- 开启限制,burst设置最多容量,nodelay决定当请求超量时,是等待处理还是返回错误码;
(3)实例
limit_req_zone $binary_remote_addr zone=req:10m rate=2r/m;
server {
listen 80;
server_name www.domain.com;
root /path/;
index index.html index.htm;
location /limit {
limit_req zone=req burst=3 nodelay;
}
# 当超过并发访问限制时,返回503错误页面
error_page 503 /503.html;
}
注意:
这两种访问控制都需要申请内存空间,既然有内存空间,当然会存在内存耗尽的情况,这时新的请求都会被返回错误,所以当开启访问量限制时,需要通过监控防止此类情况发生。
5、处理突发
(1)为什么要使用burst
如果我们在1000毫秒内接收到2个请求,怎么办?对于第二个请求,Nginx将给客户端返回错误。这可能并不是我们想要的结果,因为应用本质上趋向于突发性。
相反地,我们希望缓冲任何超额的请求,然后及时地处理它们。我们更新下配置,在limit_req
中使用burst
参数。
(2)实例
burst
参数定义了超出zone指定速率的情况下(示例中的addr
区域,速率限制在每秒1个请求),客户端还能发起多少请求。上一个请求1000毫秒内到达的请求将会被放入队列,我们将队列大小设置为5。
这意味着,如果从一个给定IP地址发送6个请求,Nginx会立即将第一个请求发送到上游服务器群,然后将余下5个请求放在队列中。然后每1000毫秒转发一个排队的请求,只有当传入请求使队列中排队的请求数超过5时,Nginx才会向客户端返回错误。
6、配置流量控制相关功能
(1)配置日志记录
默认情况下,Nginx会在日志中记录由于流量限制而延迟或丢弃的请求,如下所示:
2019/02/13 04:20:00 [error] 120315#0: *32086 limiting requests, excess: 1.000 by zone "mylimit", client: 192.168.1.2, server: nginx.com, request: "GET / HTTP/1.0", host: "nginx.com"
日志条目中包含的字段:
- limiting requests - 表明日志条目记录的是被“流量限制”请求
- excess - 每毫秒超过对应“流量限制”配置的请求数量
- zone - 定义实施“流量限制”的区域
- client - 发起请求的客户端IP地址
- server - 服务器IP地址或主机名
- request - 客户端发起的实际HTTP请求
- host - HTTP报头中host的值
默认情况下,Nginx以error
级别来记录被拒绝的请求,如上面示例中的[error]
所示(Nginx以较低级别记录延时请求,一般是info
级别)。如要更改Nginx的日志记录级别,需要使用limit_req_log_level
指令。这里,我们将被拒绝请求的日志记录级别设置为warn
(一定要定义日志位置和级别才可以)
- 错误日志级别设置为warn
- limit_req_log_level日志级别设置为warn
- 继续访问测试,看error.log日志
(2)发送到客户端的错误代码
一般情况下,客户端超过配置的流量限制时,Nginx响应状态码为503(Service Temporarily Unavailable)。可以使用limit_req_status
指令来设置为其它状态码(例如下面的404状态码):
- 修改配置文件
- 修改前
- 修改后
二、访问控制
1、Nginx访问控制模块类型
- 基于IP的访问控制:
http_access_module
- 基于用户的信任登录:
http_auth_basic_module
2、基于IP模块
配置语法:
Syntax:allow address | CIDR | unix: | all;
default:默认无
Context:http,server,location
Syntax:deny address | CIDR | unix: | all;
default:默认无
Context:http,server,location
配置设置:
#vim /etc/nginx/conf.d/access_mod.conf //修改配置文件
server {
listen 80;
server_name localhost;
location ~ ^/admin {
root /home/www/html;
index index.html index.hml;
deny 192.168.239.128; //拒绝192.168.239.128访问
allow all;
}
}
#如果先允许访问,在定义拒绝访问,那么拒绝访问不生效。
3、location拒绝所有请求
server {
listen 80;
server_name localhost;
location /foo.html {
root /home/www/html;
deny all;
}
}
4、用户的信任登录
Syntax:auth_basic string | off;
default:auth_basic off;
Context:http,server,location,limit_except
Syntax:auth_basic_user_file file;
default:默认无
Context:http,server,location,limit_except
file:存储用户名密码信息的文件。
配置实例
#mv access_mod.conf auth_mod.conf //修改配置文件
server {
listen 80;
server_name localhost;
location ~ ^/admin {
root /home/www/html;
index index.html index.hml;
auth_basic "Auth access test!";
auth_basic_user_file /etc/nginx/auth_conf;
}
}
#auth_basic不为off,开启登录验证功能,auth_basic_user-file加载账号密码文件
建立口令文件
$ mkdir /home/www/html/admin -p
$ vim /home/www/html/admin/index.html
hello boy
$ yum -y install httpd-tools //htpasswd使开源http服务器apache httpd的一个命令工具,用于生成http基本认证的密码文件
$ htpasswd -cm /etc/nginx/auth_conf user1 //第一次创建用户
$ htpasswd -m /etc/nginx/auth_conf user2 //第二次创建用户
$ cat /etc/nginx/auth_conf //查看创建的用户的密码
user1:$apr1$MOa9UVqF$RlYRMk7eprViEpNtDV0n40
user2:$apr1$biHJhW03$xboNUJgHME6yDd17gkQNb0
5、访问测试