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

相关文章

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

Python的Darts库实现时间序列预测

《Python的Darts库实现时间序列预测》Darts一个集统计、机器学习与深度学习模型于一体的Python时间序列预测库,本文主要介绍了Python的Darts库实现时间序列预测,感兴趣的可以了解... 目录目录一、什么是 Darts?二、安装与基本配置安装 Darts导入基础模块三、时间序列数据结构与

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

C#实现千万数据秒级导入的代码

《C#实现千万数据秒级导入的代码》在实际开发中excel导入很常见,现代社会中很容易遇到大数据处理业务,所以本文我就给大家分享一下千万数据秒级导入怎么实现,文中有详细的代码示例供大家参考,需要的朋友可... 目录前言一、数据存储二、处理逻辑优化前代码处理逻辑优化后的代码总结前言在实际开发中excel导入很

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Nginx部署HTTP/3的实现步骤

《Nginx部署HTTP/3的实现步骤》本文介绍了在Nginx中部署HTTP/3的详细步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学... 目录前提条件第一步:安装必要的依赖库第二步:获取并构建 BoringSSL第三步:获取 Nginx

MyBatis Plus实现时间字段自动填充的完整方案

《MyBatisPlus实现时间字段自动填充的完整方案》在日常开发中,我们经常需要记录数据的创建时间和更新时间,传统的做法是在每次插入或更新操作时手动设置这些时间字段,这种方式不仅繁琐,还容易遗漏,... 目录前言解决目标技术栈实现步骤1. 实体类注解配置2. 创建元数据处理器3. 服务层代码优化填充机制详

Python实现Excel批量样式修改器(附完整代码)

《Python实现Excel批量样式修改器(附完整代码)》这篇文章主要为大家详细介绍了如何使用Python实现一个Excel批量样式修改器,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录前言功能特性核心功能界面特性系统要求安装说明使用指南基本操作流程高级功能技术实现核心技术栈关键函

Java实现字节字符转bcd编码

《Java实现字节字符转bcd编码》BCD是一种将十进制数字编码为二进制的表示方式,常用于数字显示和存储,本文将介绍如何在Java中实现字节字符转BCD码的过程,需要的小伙伴可以了解下... 目录前言BCD码是什么Java实现字节转bcd编码方法补充总结前言BCD码(Binary-Coded Decima

SpringBoot全局域名替换的实现

《SpringBoot全局域名替换的实现》本文主要介绍了SpringBoot全局域名替换的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录 项目结构⚙️ 配置文件application.yml️ 配置类AppProperties.Ja