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

相关文章

基于 HTML5 Canvas 实现图片旋转与下载功能(完整代码展示)

《基于HTML5Canvas实现图片旋转与下载功能(完整代码展示)》本文将深入剖析一段基于HTML5Canvas的代码,该代码实现了图片的旋转(90度和180度)以及旋转后图片的下载... 目录一、引言二、html 结构分析三、css 样式分析四、JavaScript 功能实现一、引言在 Web 开发中,

SpringBoot中使用Flux实现流式返回的方法小结

《SpringBoot中使用Flux实现流式返回的方法小结》文章介绍流式返回(StreamingResponse)在SpringBoot中通过Flux实现,优势包括提升用户体验、降低内存消耗、支持长连... 目录背景流式返回的核心概念与优势1. 提升用户体验2. 降低内存消耗3. 支持长连接与实时通信在Sp

Conda虚拟环境的复制和迁移的四种方法实现

《Conda虚拟环境的复制和迁移的四种方法实现》本文主要介绍了Conda虚拟环境的复制和迁移的四种方法实现,包括requirements.txt,environment.yml,conda-pack,... 目录在本机复制Conda虚拟环境相同操作系统之间复制环境方法一:requirements.txt方法

Nginx 重写与重定向配置方法

《Nginx重写与重定向配置方法》Nginx重写与重定向区别:重写修改路径(客户端无感知),重定向跳转新URL(客户端感知),try_files检查文件/目录存在性,return301直接返回永久重... 目录一.try_files指令二.return指令三.rewrite指令区分重写与重定向重写: 请求

Spring Boot 实现 IP 限流的原理、实践与利弊解析

《SpringBoot实现IP限流的原理、实践与利弊解析》在SpringBoot中实现IP限流是一种简单而有效的方式来保障系统的稳定性和可用性,本文给大家介绍SpringBoot实现IP限... 目录一、引言二、IP 限流原理2.1 令牌桶算法2.2 漏桶算法三、使用场景3.1 防止恶意攻击3.2 控制资源

springboot下载接口限速功能实现

《springboot下载接口限速功能实现》通过Redis统计并发数动态调整每个用户带宽,核心逻辑为每秒读取并发送限定数据量,防止单用户占用过多资源,确保整体下载均衡且高效,本文给大家介绍spring... 目录 一、整体目标 二、涉及的主要类/方法✅ 三、核心流程图解(简化) 四、关键代码详解1️⃣ 设置

Nginx 配置跨域的实现及常见问题解决

《Nginx配置跨域的实现及常见问题解决》本文主要介绍了Nginx配置跨域的实现及常见问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来... 目录1. 跨域1.1 同源策略1.2 跨域资源共享(CORS)2. Nginx 配置跨域的场景2.1

Python中提取文件名扩展名的多种方法实现

《Python中提取文件名扩展名的多种方法实现》在Python编程中,经常会遇到需要从文件名中提取扩展名的场景,Python提供了多种方法来实现这一功能,不同方法适用于不同的场景和需求,包括os.pa... 目录技术背景实现步骤方法一:使用os.path.splitext方法二:使用pathlib模块方法三

CSS实现元素撑满剩余空间的五种方法

《CSS实现元素撑满剩余空间的五种方法》在日常开发中,我们经常需要让某个元素占据容器的剩余空间,本文将介绍5种不同的方法来实现这个需求,并分析各种方法的优缺点,感兴趣的朋友一起看看吧... css实现元素撑满剩余空间的5种方法 在日常开发中,我们经常需要让某个元素占据容器的剩余空间。这是一个常见的布局需求

HTML5 getUserMedia API网页录音实现指南示例小结

《HTML5getUserMediaAPI网页录音实现指南示例小结》本教程将指导你如何利用这一API,结合WebAudioAPI,实现网页录音功能,从获取音频流到处理和保存录音,整个过程将逐步... 目录1. html5 getUserMedia API简介1.1 API概念与历史1.2 功能与优势1.3