Nginx额外篇之实现Nginx限流(运维篇)

2023-10-27 19:59

本文主要是介绍Nginx额外篇之实现Nginx限流(运维篇),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.产生背景

今天上午上班突然接到同时请求,需要对Nginx做个限流,因为我们业务的特性,限流的确比把ip加入黑名单强,那么接下来就开始我的研究限流之旅。

这里先简单说下什么是限流?就是对用户访问你服务器的请求数或者连接数做个限制,不能像以前那样畅所欲为!

2.Nginx实现限流的方式

2.1 模块介绍

 Nginx特性是模块化,就由ngx_http_limit_conn_module及ngx_http_limit_req_module 2个模块组合起提供限流功能,不需要额外安装,属于Nginx内置模块,只要您安装Nginx就可以通过此模块的指令调用此功能。

ngx_http_limit_conn_module:主要用于设置用户并发连接数,一般用于服务器流量异常、负载过大,甚至是大流量的恶意攻击访问等场景。

ngx_http_limit_req_module:主要用于单个ip限流,限制单个ip的请求数,一般用于防止应用层的dos攻击,也可以被限制黑名单方式代替。

2.2 模块指令实战

1).设置最大并发数

#设置共享内存区域和允许的最大并发数。当超过此限制时,服务器将返回错误以响应请求。由ngx_http_limit_conn_module模块提供此功能。
指令:limit_conn_zone  限制共享区域大小
语法:limit_conn_zone $variable zone=name:size;    #zone = name定义区域名称,size是各个键共享内存空间大小,主要存储session会话的,官方默认值是10M

#限制并发连接数,达到真正的限速目的是由此指令提供的
语法:limit_conn zone number  #zone是limit_conn_zone定义的区域名称,number就是具体的并发连接数
contest:http,server,location

#当达到最大限制连接数后,记录日志的等级,会输出到Nginx错误日志中。    
语法:limit_conn_log_level info|notice|warn|error; 
默认值:limit_conn_log_leve error;
生效区间:http,server,location

#当达到最大限制连接数后,向客户端返回特定的错误码
语法:limit_conn_status code;
默认值:limit_conn_status 503;
生效范围:http,server,location

示例如下:

示例:
limit_conn_zone $binary_remote_addr zone=addr:10m;  #这里是设置共享内存空间
limit_conn_log_level error;  #这是指错误日志记录级别(加不加影响不大)
limit_conn_status 503; #返回503状态(针对超过限制值的请求)server {location /download/ {limit_conn addr 1;       #设置最大并发数,也就是当客户端同时发起2个访问时,就返回503
}实例:
#限制最大并发数
root@test:/usr/local/nginx/conf/vhost 18:28:50 
$ cat ../nginx.conf | grep limit | grep -v "^wor" | egrep  -v '#'
limit_conn_zone $binary_remote_addr zone=one:10m;$ cat  7250.conf 
server {listen 80;server_name ab.text.com;
......limit_conn one 2;      #对并发进行限制,一般放在server字段或者location字段。#limit_rate_after 80M;    #指定在发送多少数据后就进行限速#limit_rate 600k;    #limit_rate指定每秒返回的字节数......$ cat /data/www/index.php    #测试文件,以动态文件为主,静态文件获取太快,很难得到结果
<?php echo 1;usleep(50000);
?>#测试(默认是平滑加载Nginx.conf了) 
$ ab -c 2  -n 9  ab.text.com/index.php                  # -c 是指并发数 -n是请求数
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking ab.text.com (be patient).....doneServer Software:        nginx
Server Hostname:        ab.text.com
Server Port:            80Document Path:          /index.php
Document Length:        2 bytesConcurrency Level:      2              #我总共发起了2个并发,所以并发数为2
Time taken for tests:   0.036 seconds
Complete requests:      9              #我总共发起了9个请求,这里完成请求数就为9
Failed requests:        0              #失败为0,在2个并发下发起9个请求,完全被处理$ ab -c 3  -n 9  ab.text.com/index.php
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking ab.text.com (be patient).....doneServer Software:        nginx
Server Hostname:        ab.text.com
Server Port:            80Document Path:          /index.php
Document Length:        2 bytesConcurrency Level:      3  #发起3个并发,比我设置的值多一个并发
Time taken for tests:   0.014 seconds
Complete requests:      9  #还是完成9个请求
Failed requests:        6  #但是失败6个请求,如果在php5.6的话应该是失败3个请求,7的话不知道为啥失败6个请求(我们目的是研究并发,php问题先放放)根据上述结果:limit_conn one指令对并发的限制是非常明显的

2).对单个ip进行限流

ngx_http_limit_req_module是Nginx的默认编译模块,主要用限制每个客户端每秒的请求数简单来说是限流。只是表现在对请求次数的限制,但是并非所有连接都被计数。只有被服务器处理的用户请求连接,才会被进行计数。
涉及算法: leaky bucket算法,又熟称漏桶算法。

简单来说,根据ngx_http_limit_req_module进行限流后,可以把突发的流量以一个平稳的速度进行数据传输,但是也会出现相应的情况那就是用户响应变慢。

原理:首先在内存中创建一个内存共享存储池,也就是下面那个大碗,然后将用户的请求都存储到这个碗里,在然后按照既定的速度对用户请求进行处理返回响应。如果这个大碗满了,Nginx将返回错误码并且拒绝接收用户请求。

ngx_http_limit_req_module4个指令如下:

#定义共享内存,key关键字及限制速率
语法:limit_red_zone key zone=name:size rate=rates/; #key 关键字 zone创建缓存空间 rate设置速率
生效范围:http
rate的单位是r/s或者r/m,是指每分钟能处理多少个请求。r对应的是请求数

#限制并发连接数
语法:limit_red zone = name [burst=number][nodelay];
生效范围:http,server,location
burst默认值为0,就那个大碗
设置了nodelay,就会对burst中的请求不在采用延迟处理,而是立即返回错误。

#达到最大上限值记录日志级别
语法:limit_red_log_lever info|notice|warn|error;
默认值:limit_red_log_level error;
生效范围:http,server,location

#达到最大上限值,向客户端返回特定的错误码
语法:limit_red_status code;
默认值:limit_red_status 503;
生效范围:http,server,location


示例如下:

示例:
http {limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;limit_red_log_level errorlimit_red_status 503...server {...location /search/ {limit_req zone=one burst=5;  }实例:
$ cat ../nginx.conf | grep limit | grep -v '^worker'limit_req_zone $binary_remote_addr zone=name:10m rate=10r/s; ##rate=10r/s  是指每s只能处理10个请求,你也可以设置为 rate=20r/s,30..等等,后面是数字代表请求数,其他的默认就好。$ cat  7250.conf  
server {listen 80;server_name ab.text.com;
......limit_req zone=name burst=5;  #burst 指的是突发数
.....}注:测试文件还是上面那个index.php测试:
$ ab -n 100 ab.text.com/index.php
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking ab.text.com (be patient).....doneServer Software:        nginx
Server Hostname:        ab.text.com
Server Port:            80Document Path:          /index.php
Document Length:        2 bytesConcurrency Level:      1
Time taken for tests:   9.907 seconds #这里耗时9.9s,也就是说1s只处理了10个请求,达到预期
Complete requests:      100     #完成请求100个,跟我们期望值一样
Failed requests:        0

3).额外的限流指令 那就是 limit_rate 指令了,可以加载server,location,http字段的话没有试过!

limit_rate_after number,也就是对这个值不进行限速

limit_rate  number,也就是对超过limit_rate_after值的流量进行限速。

起来是不是感觉有点拗口,别怕,直接上实例说明:

实例:
$ cat 7250.conf
server {listen 80;server_name ab.text.com;
......limit_rate_after 90M;    #这个是指对前90M内容不限速limit_rate 600k;   #这个是指对90M之后的内容限速为600Kb每S......
}废话不多说,直接来个下载瞧瞧

浏览器访问:ab.text.com/jdk1 

注:是不是在前面快的飞起,达到10M/S,然后后面是只有500多KB无限接近600KB/S,那就代表达到我们的理想效果。

关于限流的知识就介绍到这里,还有个worker_connections限制文件打开数的话,不知道怎么测试就在这里不说了,当然欢迎各位看官留言讨论。

参考文章:

https://baike.so.com/doc/2372586-2508646.html

https://baike.so.com/doc/1712488-1810506.html

这篇关于Nginx额外篇之实现Nginx限流(运维篇)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/288019

相关文章

SpringBoot3实现Gzip压缩优化的技术指南

《SpringBoot3实现Gzip压缩优化的技术指南》随着Web应用的用户量和数据量增加,网络带宽和页面加载速度逐渐成为瓶颈,为了减少数据传输量,提高用户体验,我们可以使用Gzip压缩HTTP响应,... 目录1、简述2、配置2.1 添加依赖2.2 配置 Gzip 压缩3、服务端应用4、前端应用4.1 N

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Python FastAPI+Celery+RabbitMQ实现分布式图片水印处理系统

《PythonFastAPI+Celery+RabbitMQ实现分布式图片水印处理系统》这篇文章主要为大家详细介绍了PythonFastAPI如何结合Celery以及RabbitMQ实现简单的分布式... 实现思路FastAPI 服务器Celery 任务队列RabbitMQ 作为消息代理定时任务处理完整

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

MySQL双主搭建+keepalived高可用的实现

《MySQL双主搭建+keepalived高可用的实现》本文主要介绍了MySQL双主搭建+keepalived高可用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、测试环境准备二、主从搭建1.创建复制用户2.创建复制关系3.开启复制,确认复制是否成功4.同

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

Java实现时间与字符串互相转换详解

《Java实现时间与字符串互相转换详解》这篇文章主要为大家详细介绍了Java中实现时间与字符串互相转换的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一、日期格式化为字符串(一)使用预定义格式(二)自定义格式二、字符串解析为日期(一)解析ISO格式字符串(二)解析自定义

opencv图像处理之指纹验证的实现

《opencv图像处理之指纹验证的实现》本文主要介绍了opencv图像处理之指纹验证的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录一、简介二、具体案例实现1. 图像显示函数2. 指纹验证函数3. 主函数4、运行结果三、总结一、