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

相关文章

C++使用栈实现括号匹配的代码详解

《C++使用栈实现括号匹配的代码详解》在编程中,括号匹配是一个常见问题,尤其是在处理数学表达式、编译器解析等任务时,栈是一种非常适合处理此类问题的数据结构,能够精确地管理括号的匹配问题,本文将通过C+... 目录引言问题描述代码讲解代码解析栈的状态表示测试总结引言在编程中,括号匹配是一个常见问题,尤其是在

Java实现检查多个时间段是否有重合

《Java实现检查多个时间段是否有重合》这篇文章主要为大家详细介绍了如何使用Java实现检查多个时间段是否有重合,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录流程概述步骤详解China编程步骤1:定义时间段类步骤2:添加时间段步骤3:检查时间段是否有重合步骤4:输出结果示例代码结语作

Nginx设置连接超时并进行测试的方法步骤

《Nginx设置连接超时并进行测试的方法步骤》在高并发场景下,如果客户端与服务器的连接长时间未响应,会占用大量的系统资源,影响其他正常请求的处理效率,为了解决这个问题,可以通过设置Nginx的连接... 目录设置连接超时目的操作步骤测试连接超时测试方法:总结:设置连接超时目的设置客户端与服务器之间的连接

使用C++实现链表元素的反转

《使用C++实现链表元素的反转》反转链表是链表操作中一个经典的问题,也是面试中常见的考题,本文将从思路到实现一步步地讲解如何实现链表的反转,帮助初学者理解这一操作,我们将使用C++代码演示具体实现,同... 目录问题定义思路分析代码实现带头节点的链表代码讲解其他实现方式时间和空间复杂度分析总结问题定义给定

Java覆盖第三方jar包中的某一个类的实现方法

《Java覆盖第三方jar包中的某一个类的实现方法》在我们日常的开发中,经常需要使用第三方的jar包,有时候我们会发现第三方的jar包中的某一个类有问题,或者我们需要定制化修改其中的逻辑,那么应该如何... 目录一、需求描述二、示例描述三、操作步骤四、验证结果五、实现原理一、需求描述需求描述如下:需要在

如何使用Java实现请求deepseek

《如何使用Java实现请求deepseek》这篇文章主要为大家详细介绍了如何使用Java实现请求deepseek功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1.deepseek的api创建2.Java实现请求deepseek2.1 pom文件2.2 json转化文件2.2

python使用fastapi实现多语言国际化的操作指南

《python使用fastapi实现多语言国际化的操作指南》本文介绍了使用Python和FastAPI实现多语言国际化的操作指南,包括多语言架构技术栈、翻译管理、前端本地化、语言切换机制以及常见陷阱和... 目录多语言国际化实现指南项目多语言架构技术栈目录结构翻译工作流1. 翻译数据存储2. 翻译生成脚本

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

Python如何实现PDF隐私信息检测

《Python如何实现PDF隐私信息检测》随着越来越多的个人信息以电子形式存储和传输,确保这些信息的安全至关重要,本文将介绍如何使用Python检测PDF文件中的隐私信息,需要的可以参考下... 目录项目背景技术栈代码解析功能说明运行结php果在当今,数据隐私保护变得尤为重要。随着越来越多的个人信息以电子形

使用 sql-research-assistant进行 SQL 数据库研究的实战指南(代码实现演示)

《使用sql-research-assistant进行SQL数据库研究的实战指南(代码实现演示)》本文介绍了sql-research-assistant工具,该工具基于LangChain框架,集... 目录技术背景介绍核心原理解析代码实现演示安装和配置项目集成LangSmith 配置(可选)启动服务应用场景