nginx-限流(请求/并发量)

news2025/1/8 1:19:28

一. 简述:

     在做日常的web运维工作中,难免会遇到服务器流量异常,负载过大等情况。恶意攻击访问/爬虫等非正常性请求,会带来带宽的浪费,服务器压力增大,影响业务质量。

二. 限流方案:

对于这种情况, 一般可考虑通过nginx的ngx_http_limit_conn_module模块和ngx_http_limit_req_module 模块限制同一client ip的请求量和并发数来防范。

1. ngx_http_limit_conn_module模块(限制连接数[并发])

       limit_conn_zone

       语法: limit_conn_zone $variable zone=name:size;
       默认值: none
       配置段: http

    $variable定义键(键的状态中保存了当前连接数),zone=name定义区域名称,后面的limit_conn指令会用到的。size定义各个键共享内存空间大小(当共享内存空间被耗尽,服务器将会对后续所有的请求返回 503 错误。)。
limit_conn_log_level
语法:limit_conn_log_level info | notice | warn | error
默认值:error
配置段:http, server, location
当达到最大限制连接数后,记录日志的等级。
limit_conn
语法:limit_conn zone_name number
默认值:none
配置段:http, server, location
指定每个给定键值的最大同时连接数,当超过这个数字时被返回503

limit_conn_status
语法: limit_conn_status code;
默认值: limit_conn_status 503;
配置段: http, server, location
该指定在1.3.15版本引入的。指定当超过限制时,返回的状态码。默认是503。

limit_rate
语法:limit_rate rate
默认值:0
配置段:http, server, location, if in location
对每个连接的速率限制。参数rate的单位是字节/秒,设置为0将关闭限速。 按连接限速而不是按IP限制,因此如果某个客户端同时开启了两个连接,那么客户端的整体速率是这条指令设置值的2倍。

2. ngx_http_limit_req_module模块(限制请求数)

 limit_req_zone

语法: limit_req_zone $variable zone=name:size rate=rate;
默认值: none
配置段: http

设置一块共享内存限制域用来保存键值的状态参数,速度可以设置为每秒处理请求数和每分钟处理请求数,其值必须是整数,所以如果你需要指定每秒处理少于1个的请求,2秒处理一个请求,可以使用 “30r/m”

limit_req_log_level
语法: limit_req_log_level info | notice | warn | error;
默认值: limit_req_log_level error;
配置段: http, server, location
设置你所希望的日志级别

limit_req_status
语法: limit_req_status code;
默认值: limit_req_status 503;
配置段: http, server, location

limit_req
语法: limit_req zone=name [burst=number] [nodelay];
默认值: —
配置段: http, server, location
设置对应的共享内存限制域和允许被处理的最大请求数阈值。 如果请求的频率超过了限制域配置的值,请求处理会被延迟,,当被延迟的请求数超过了定义的阈值,这个请求会被终止,并返回503;nodelay:表示当超过访问次数并缓冲也满的情况下,直接放回503错误,若不设置,这些多余的请求会延迟处理 。

三. 实际运用案例:

    一般情况下key使用$binary_remote_addr(建议使用)或者$remote_addr变量二者区别在于: $remote_addr变量的长度为7字节到15字节,而存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。$binary_remote_addr变量的长度是固定的4字节,存储状态在32位平台中占用32字节或64字节,在64位平台中占用64字节。1M共享空间可以保存3.2万个32位的状态,1.6万个64位的状态。当恭喜内存空间被耗尽时,服务会对后续请求返回503(切记).

http{
    .........
    limit_conn_zone $binary_remote_addr zone=addr:1000m;
    limit_req_zone $binary_remote_addr zone=addrs:1000m  rate=10r/s;  #每秒请求10次
    ...........
    server{
        ......
        limit_conn  addr  10;   #限制并发数为10
        limit_req zone=addrs burst=5 nodelay;   #允许超出请求5(排队/延迟)
        ......
        }
    }
#注  limit_conn_zone 和limit_req_zone可单独使用

除以上以$binary_remote_addr变量为key外,还有一种情况,如前端使用了代理层,CDN等服务,这种情况下$binary_remote_addr变量会是代理层/CDN的ip,就无法通过$binary_remote_addr变量做限制, 目前知道有两种解决方式,一种是使用白名单, 另外一种是配置$http_x_forwarded_for然后取逗号分隔的第一个ip(即源ip,不太好的消息就是这个变量字段是可以通过修改请求head信息进行伪造(curl -H "X-Forwarded-For:192.168.0.1,192.168.0.2" http://127.0.0.1 ))。白名单的方式后续再说。这里先说下第二种方法, 可通过nginx的map模块做正则匹配后映射请求源ip, 具体配置如下:

1)代理层的配置:

    upstream renren_trans_1 {
        server 10.5.11.12;
    }

    server {
        listen  80;
        server_name zabbixtest.d.xiaonei.com;
        http_accounting_id  zabbixtest;
        location / {
                proxy_pass         http://renren_trans_1;
                proxy_set_header   Host             $host;
                proxy_set_header   X-Real-IP        $remote_addr;
                proxy_set_header  X-Forwarded-For  $proxy_add_x_forwarded_for;
                client_max_body_size       50m;
                client_body_buffer_size    128k;
                client_body_temp_path      /data/client_body_temp;
                proxy_connect_timeout      15;
                proxy_send_timeout         300;
                proxy_read_timeout         300;
                proxy_buffer_size          8k;
                proxy_buffers              4 32k;
                proxy_busy_buffers_size    64k;
                proxy_temp_file_write_size 64k;
                proxy_temp_path            /data/proxy_temp;
        }
    }

代理层后端(业务机)配置:

    map $http_x_forwarded_for $clientips {

        "" $remote_addr;                        #当为空时映射$remote_addr 到$clientips
        ~^(?P<firstip>[0-9\.]+),?.*$ $firstip;  #获取第一个ip
    }


    limit_conn_zone $clientips zone=addr:1000m;
    limit_req_zone $clientips zone=addrs:1000m  rate=10r/s;

    limit_req zone=addrs burst=5 nodelay;
    server {
        listen       80;
        server_name  localhost;

        limit_conn  addr  10;
        limit_req zone=addrs burst=5 nodelay;
        #charset koi8-r;

        #access_log  logs/host.access.log  main;

测试:

  1) 测试通过代理层访问的方式:

# ab -c 11 -t 10 http://zabbixtest.d.xiaonei.com/test.html

access.log内容如下:

可发现大量503 error(第一列代理层,最后一列源ip) 。

2) 测试直接访问,不通过代理层;

# ab -c 5 -t 10 http://10.5.11.12/test.html

access.log如下:

同样会出现大量503 ,代理ip为空!

 ----------------------------------------------------------------------------------------------

深耕运维行业多年,擅长linux、容器云原生、运维自动化等方面。
承接各类运维环境部署、方案设计/实施、服务代运维工作,欢迎沟通交流 !

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2272935.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学Rust开发CAD】1 环境搭建

文章目录 一、搭建C/C编译环境二、安装Rust三、配置 PATH 环境变量四、验证安装结果五、安装编辑工具 一、搭建C/C编译环境 Rust 的编译工具依赖 C 语言的编译工具&#xff0c;这意味着你的电脑上至少已经存在一个 C 语言的编译环境。如果你使用的是 Linux 系统&#xff0c;往…

模型创新、论文复现、科研辅导、论文代码定制

建模先锋团队长期致力于为用户提供优质的代码定制服务。团队提供全网最低价格的服务&#xff0c;同时保证高性价比和高质量的代码交付&#xff0c;为您提供个性化定制的服务。 以下是定制服务范围&#xff1a; 通过深度学习和信号处理技术&#xff0c;我们能够针对不同行业和场…

基于云效 Windows 构建环境和 Nuget 制品仓库进行 .Net 应用开发

作者&#xff1a;陆冬澄、周静 在现代软件研发体系中&#xff0c;.NET 平台由于其强大的功能、灵活性和丰富的开发工具&#xff0c;成为了构建 Windows 应用程序的热门选择。无论是桌面应用、Web 应用还是服务应用&#xff0c;.NET 提供了一系列强大的框架和工具&#xff0c;帮…

用VS C#构建Windows服务【纯操作版,附带项目地址】

1&#xff0e;点击“创建新项目”&#xff0c;选择“Windows 服务&#xff08;.NET Framework&#xff09;” 2、给项目命名 3、双击“Service1.cs”&#xff0c;右键&#xff0c;选择“添加安装程序”&#xff0c;就会生成一个“ProjectInstaller.cs”文件 4、双击“P…

KUKA机器人如何修改程序并下载到机器人控制器中?

KUKA机器人如何修改程序并下载到机器人控制器中? 如下图所示,首先将使用的网卡的IP地址设置为自动获得, 打开workvisual软件,点击搜索,正常情况下可以搜索到项目文件,选中后双击进入, 如下图所示,此时,workvisual会自动从机器人控制器中下载项目文件到电脑上,耐心等待…

L28.【LeetCode笔记】移动零(三种解法)

目录 1.题目 2.向前覆盖法 分析 代码 提交结果 3.优解:双指针 代码 提交结果 4.其他不符合题意的方法:使用队列 代码 提交结果 1.题目 https://leetcode.cn/problems/move-zeroes/description/ 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾…

js逆向实战(1)-- 某☁️音乐下载

下载某云音乐源文件.mp4格式 首先随便点进一首歌&#xff0c;如图所示获取该音乐id&#xff0c;然后点击播放键&#xff0c;打开F12进行查询XHR 由此可知&#xff0c;实际请求网址是 https://music.163.com/weapi/song/enhance/player/url/v1?csrf_token「你的token」url需带…

深入了解 SSL/TLS 协议及其工作原理

深入了解 SSL/TLS 协议及其工作原理 一. 什么是 SSL/TLS?二. SSL/TLS 握手过程三. SSL/TLS 数据加密与传输四. 总结 点个免费的赞和关注&#xff0c;有错误的地方请指出&#xff0c;看个人主页有惊喜。 作者&#xff1a;神的孩子都在歌唱 一. 什么是 SSL/TLS? 安全套接层&am…

Java四大常用JSON解析性能对比:Hutool、Fastjson2、Gson与Jackson测试

1. 引言 JSON 是现代软件开发中常用的数据交换格式&#xff0c;尤其在微服务和前后端分离的架构中更是必不可少。 本文将对 Java 中四大主流 JSON 解析库——Hutool、Fastjson2、Gson 和 Jackson 进行性能测试和对比分析&#xff0c;通过实测 20 万条数据解析&#xff0c;揭示…

【整理集合大全】MySQL(4) 数据库增删改查SQL语句

查看数据库 show databases; 使用数据库 use 数据库名;创建数据库 CREATE DATABASE 数据库名;删除数据库 DROP DATABASE 数据库名;创建表 create table 表名(列名1 类型(长度) [约束],列名2 类型(长度) [约束],…… );长度区别 int类型带长度&#xff1a;不影响存取值&…

升级 Spring Boot 3 配置讲解 —— Spring Boot 3 核心源码专讲

学会这款 &#x1f525;全新设计的 Java 脚手架 &#xff0c;从此面试不再怕&#xff01; Spring Boot 3 是 Spring 生态中的重要里程碑&#xff0c;它不仅全面支持 Java 17&#xff0c;还引入了许多新特性&#xff0c;如对 GraalVM 原生镜像的支持、改进的性能优化以及更灵活的…

vue3中el-table实现多表头并表格合并行或列

1、el-table中添加事件 :span-method"genderSpanCity" <el-table :span-method"genderSpanCity":data"data.tableData":fit"true" table-layout"fixed" header-align"center" stripestyle"width:100%;he…

OpenGL —— 流媒体播放器 - ffmpeg解码rtsp流,opengl渲染yuv视频(附源码,glfw+glad)

效果 说明 FFMpeg和OpenGL作为两大技术巨头,分别在视频解码和图形渲染领域发挥着举足轻重的作用。本文将综合两者实战视频播放器,大概技术流程为:ffmpeg拉取rtsp协议视频流,并经过解码、尺寸格式转换为yuv420p后,使用opengl逐帧循环渲染该yuv实时视频。 核心源码 vertexSh…

Web安全扫盲

1、建立网络思维模型的必要 1 . 我们只有知道了通信原理&#xff0c; 才能够清楚的知道数据的交换过程。 2 . 我们只有知道了网络架构&#xff0c; 才能够清楚的、准确的寻找漏洞。 2、局域网的简单通信 局域网的简单通信&#xff08;数据链路层&#xff09; 一般局域网都通…

HTML 显示器纯色亮点检测工具

HTML 显示器纯色亮点检测工具 相关资源文件已经打包成html等文件&#xff0c;可双击直接运行程序&#xff0c;且文章末尾已附上相关源码&#xff0c;以供大家学习交流&#xff0c;博主主页还有更多Html相关程序案例&#xff0c;秉着开源精神的想法&#xff0c;望大家喜欢&#…

ARM发布Armv9.5架构:迈向更强性能与灵活性的新时代

2024年11月30日&#xff0c;ARM正式发布了其最新的Armv9.5架构&#xff0c;这是Arm技术发展的又一重要里程碑。从表中信息来看&#xff0c;Armv9.5架构的发布标志着该公司的架构系列在性能、灵活性和可扩展性方面取得了进一步突破。本次发布不仅是技术上的提升&#xff0c;更是…

被催更了,2025元旦源码继续免费送

“时间从来不会停下&#xff0c;它只会匆匆流逝。抓住每一刻&#xff0c;我们才不会辜负自己。” 联系作者免费领&#x1f496;源&#x1f496;码。 三联支持&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;亲爱的朋友们&#xff0c;感谢你…

【Rust自学】10.4. trait Pt.2:trait作为参数和返回类型、trait bound

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 说句题外话&#xff0c;写这篇的时间比写所有权还还花的久&#xff0c;trait是真的比较难理解的概念。 10.4.1. 把trait作为参数 继续以…

R机器学习:神经网络算法的理解与实操,实例解析

神经网络算法是一种模仿生物神经网络&#xff08;尤其是人脑&#xff09;结构和功能的算法。它由大量相互连接的节点&#xff08;称为神经元&#xff09;组成&#xff0c;这些神经元组织成层&#xff0c;通过传递信号来处理信息。神经网络算法在机器学习、人工智能等领域中扮演…

Java(day4)

二维数组 静态初始化 动态初始化 练习 public class test1 {public static void main(String[]args){int arr[][]{{22,66,44},{77,33,88},{25,45,65},{11,66,99}};int sum0;for(int i0;i<arr.length;i){int a0;for(int j0;j<arr[i].length;j){sumarr[i][j];aarr[i][j];…