Nginx: 配置项之http模块connection和request的用法以及limit_conn和limit_req模块

connection和request

  • connection 就是一个连接, TCP连接
    • 客户端和服务器想要进行通信的话,有很多种方式
    • 比如说, TCP的形式或者是UDP形式的
    • 通常很多应用都是建立在这个TCP之上的
    • 所以, 客户端和服务器通信,使用了TCP协议的话,必然涉及建立TCP连接
    • 也就是通常所说的三次握手
  • TCP协议它是一个有状态的一个协议,它是有一个完整的状态机的
    • 通过那个状态位的不同变化来判断分析的
  • 如果先建立了这个TCP连接之后,接下来就可以发送应用层的数据信息
    • 比如 HTTP 请求,这就是一个 request
    • 这个 request 它是必须建立在 我们的connection之上的
    • HTTP协议, 它又是一个无状态的协议
  • 所以说connection和request他们连个基本的关系是
    • 首先要建立 connection 之后才需要去发送 request
    • 这个 connection 和 request 之间对应的关系并非一对一的
    • 在打开长连接的过程中,可能在一个 connection 中会发送很多的HTTP的requests请求
  • 请求示意图
  • 我的客户端想要跟服务器通信去获取服务器上某一些网站的信息
  • 就简单以浏览网页这种形式来说,送一个请求
  • 也就是在浏览器中去刷新一个URL, 它会发生哪些事呢?
    • 第一个肯定需要去建立一个connection,也就发起一个TCP的一个连接
    • 客户端首先会给服务器发送一个带有SYN的一个数据包
    • 服务器收到这个数据包之后就知道客户端是想发起一个TCP连接
    • 它会回应客户端发送的SYN包,并且也发送一个ACK同时它也有一个SYN的标志
    • 客户端收到以后给服务器发送一个ACK
    • 至此,三次握手就完成了,建立了一个TCP连接
    • 那TCP连建立完成之后,这个客户端就可以去发送具体的一个HTTP请求
  • 比如我们在 www.baidu.com 中访问
    • 这个时候, 请求的是提供的web服务器上的某一个或多个文件
    • 默认是80端口,对应我们服务器上的一个外部应用
    • 这个时候网站首页中可能包含了很多信息,会发起多个 request 请求
    • 这个时候在一个TCP连接之中,可能会对应多个 request 的请求
    • 开启了这个长连接的情形下,它为了加速效率
    • 会允许你一个connection连接中发送很多个 request
    • 同时服务器回应很多 response 报文
  • request请求都是要建立在connection之上

limit_conn 模块


1 )基本功能

  • 用于限制客户端并发连接数
  • 默认编译进 nginx, 通过 --without-http_limit_conn_module 禁用
  • 使用共享内存,对所有worker子进程生效
    • 如果需要对客户端的并发连接进行限制的话
    • 对于一个特定的客户端来说,他第一次发起一个HTTP的请求
    • 这个请求被某一个worker子进程所处理
    • 假如, 他下一次再发起的这个HTTP请求, 有可能受会到另外一个 worker 子进程
    • 因此, 想要对所有客户端连接进行一个统一的控制
    • 不同的worker子进程之间必须知道某一个客户端发送过来的连接有几个
    • 必须要有一块共享内存, 在共享内存中,我们需要去维护这样一个数据结构
    • 这个数据结构中能够保存特定客户端所发送过来的已经建立的这个连接数
    • 因此,即使某一次请求被录入到不同的work子进程之后
    • 我们的worker子进程也能够去这样一个共享内存中去取出这块数据结构中
    • 已经存储的客户端所建立的连接数,从而对客户端的一个连接数进行限制

2 )常用指令

  • limit_conn_zone, 其实这个zone指令就是用来定义共享内存的
  • limit_conn_status, 主要是用来定义限制行为发生的时候,返回给客户端的一个状态
  • limit_conn_log_level,限制行为发生的时在日志中所记录的这个日志等级
  • limit_con,这个才是真正去定义客户端的限制的一个并发连接数

那我们来逐个的看每一个指令,它的一个具体用法

2.1 ) limit_conn_zone

  • 语法: limit_conn_zone key zone=name:size
    • 这是一个固定写法,后面空格会跟一个key
    • 这个 key 是一个唯一性的标识,用来标识客户端的唯一性的
    • 比如说, 可以根据客户端的一个IP来做客户端的唯一性标识
    • 通常情况下,我们会使用一个变量叫一个 $remote_addr 这样一个变量
    • 这个是在Nginx 中所内置的一个变量
    • 也就是说,当我们部署好Nginx, 你的客户端发送一个请求过来以后
    • 在请求中会带上这个 $remote_addr, Nginx会将客户端的IP赋值给 $remote_addr
    • 因此用来识别客户端的一个键,可以根据客户端唯一性标识这个IP来对客户端进行限制
    • 当然还有很多一些其他的限制,比如说我们可以根据客户端建立的时候
    • 有很多token信息来进行一个唯一的token信息来进行一个限速
    • 当然不同的形式,需要根据自己的应用场景去定义
    • 在实际的应用场景,通常用的最多的都是这个 $remote_addr
    • 那在很多情形下,如果存在反向代理的情形,可能通过反向代理中
    • 加一个指定的 real_ip 的指令,获取到 real_ip 对 real_ip 进行限速
    • 总之,key就是用来定义所限速客户端那个唯一性标识
    • 之后 zone=name:size 是一个固定写法,这个name是任意名称都行
    • 后面跟一个冒号 和 size,这个size是定义共享内存的空间,以M为单位
  • 默认值: 无
  • 上下文: http (只能定义在 http 段中,即在http的全局配置信息中定义)
  • 示例: limit_conn_zone $binary_remote_addr zone=addr:10m
    • $binary_remote_addr 和 $remote_addr 都是标记客户端ip信息的
    • $binary_remote_addr 好处是只使用4个字节的空间,提升处理效率
    • $remote_addr 会占用 7 - 15 个字节
    • 这里 10m 一般足够使用

2.2 )limit_conn_status

  • 语法:limit_conn_status code
    • code 是状态码,比如:201, 302,404,…
  • 默认值: limit_conn_status 503;
  • 上下文:http、server、location

2.3 ) limit_conn_log_level

  • 语法: limit_conn_log_level info | notice | warn | error;
    • 比如说当我们这个限制行为发生的时候,根据客户的IP来限速
    • 我们把它限速为一个并发连接,超过一个并发连接的时候, 不处理,返回503状态码
    • 同样,在对应的 log 中进行记录
  • 默认值:limit_conn_log_level error;
  • 上下文:http、server、location

2.4 ) limit_conn

  • 语法:limit_conn zone number;
    • 前面的 limit_conn_zone 已经定义了某一个名称的一个共享内存,指定了大小空间
    • 这个时候可以直接使用, 这个 zone 其实是要引用前面定义的addr的名称的那个定义
    • 之后number就是限速多少
  • 默认值: 无
  • 上下文:http、server、location

3 ) 配置示例

  • 我们想要根据 $binary_remote_addr 也就是客户端的IP去限速
  • 并且把每一个客户端IP限速为2,只要超过2个链接,就给它限制住
  • 超过2个链接,就直接给他返回 503

示例

http {limit_conn_zone   $binary_remote_addr zone=limit_addr:10m # 这个只能在 http 段中server {listen      	           80;server_name     localhost;location / {root     html;index   index.html  index.htm;limit_status 503;limit_conn_log_level warn;limit_conn limit_addr 2;limit_rate  50;}}
}

重启

  • $ /opt/nginx/sbin/nginx -s reload
  • 开启 多个 curl 终端 进行 curl localhost,前2个窗口有结果,后面就会 503

limit_req 模块


1 ) 基本功能

  • 用于限制客户端处理请求的平均速率

  • 默认编译进 nginx, 通过 --without-http_limit_req_module 禁用

  • 使用共享内存, 对所有 woker 子进程生效

  • 限流算法: leaky_bucket

上图是算法思想思路

  • 它所使用的一个限流算法是一个 leaky_bucket 的算法,limit_req 模块本身类似于一个限流的模块
  • 有一些很经典的一些限流算法:比如说像 leaky_bucket 算法,计算器算法(固定窗口),令排桶算法等等
  • 这些都是在高并发系统中经常使用的一个限流的一个算法
  • 在 Bursty data 图表中,横坐标是一个时间轴,纵坐标是一个流量的轴
  • 假如说,随着时间的推移,流量是不均匀的,前两秒钟,它的流量达到了 12 Mbps
  • 之后第2秒到第7秒中间没有任何流量, 之后第7秒到第10秒之间, 又平均是2 Mbps的一个流量
  • 在这十秒钟,它一共有 12 * 2 + 2 * 3 = 30M 的流量,但是分布很不均匀
  • 前2秒突发比较大,2 - 7 s 没有流量, 7 - 10 s 流量较少
  • 这个 lkeybucket 算法就是实现了将流量削平来进行限流的动作
  • 它把这些突发的流量,包括中间没有的流量给强行的限制到某一个速率上来进行处理
  • 也就是 30 / 10 = 3Mbps 的速率,它类似于一个水龙头,使用这样一个漏斗来进行处理
  • 从水龙头滴出来的水类似于我们的流量,水龙头的开关大小都用来模拟流量的一个大小
  • 对于在这漏斗下面出水的一个速率,它是一个恒定的
  • 这个漏桶算法最重要的功能就是实现一个削平流量
  • 将突发的流量和不均匀的流量来进行一个强行恒定到某一个数据上来进行处理
  • 上面有一个 Bursty flow, Bursty的参数类似于用来定义这样一个桶的大小
  • 现在以 3Mbps 的速率来消费这些流量,但是这个流量峰值可能远远超过了3M这样一个流量
  • 只要我这个桶没有满的情形下,这个服务是不会被拒绝的
  • 只有说这个漏斗中的水完全满了之后,流量完全超过了这个桶的大小之后的才会被拒绝

2 )常见指令

2.1 limit_req_zone

  • 用于定义共享内存
  • 语法:limit_req_zone key zone=name:size rate=rate
  • 默认值: 无
  • 上下文:http
  • 示例: limit_req_zone $binary_remote_addr zone=one:10m rate=2r/m
    • rate=2r/m 每分钟2个请求
    • 它会平均处理,比如30s之后再处理第二个

2.2 limit_req_status

  • 语法:limit_req_status code;
  • 默认值:limit_req_status 503;
  • 上下文: http、server、location

2.3 limit_req_log_level

  • 语法: limit_req_log_level info | notice | warn | error;
  • 默认值: limit_req_log_level error;
  • 上下文: http、server、location

2.4 limit_req

  • 语法:limit_req zone=name [burst=number] [nodelay | delay=number];
    • 这里 burst 就是用来定义桶的大小
    • 想要它立即返回的话,必须加个 nodelay 选项
  • 默认值: 无
  • 上下文: http、server、location
  • 示例
    • limit_req zone=one;
    • limit_conn zone=one burst=5 nodelay;

3 ) 配置示例

http {# 注意下面的定义limit_req_zone $binary_remote_addr zone=limit_req:15m rate=2r/m; # 这里rate设置的很小,用于演示server {listen      	           80;server_name     localhost;location / {root          html;index         index.html  index.htm;error_log     logs/limit_req_error.log       info; # 这个配置是特意加上的,用于查看错误输出# 注意下面的定义limit_req_status 504;limit_req_log_level notice;limit_req zone=limit_req; # 0s - 30s 内第一次,30s - 1m内 第二次,如果在0s-30s收到第二次请求则返回504# limit_req zone=limit_req burst=7 nodelay; # 定义 burst 选项,30s之内会继续返回,不会504, 直到 7次之后}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java JNA调用C函数常见问题及解决方法

目录 1 undefined symbol:xxx2 Java映射C数组乱码3 Java使用String接收不到C函数返回的char*4 Unable to load DLL xxx.dll5 java.lang.UnsatisfiedLinkError: %1 不是有效的 Win32 应用程序6 无效的ELF头7 Structure array elements must use contiguous memory8 j…

msvcp120.dll丢失是怎么回事?几种靠谱修复msvcp120.dll的方法

在使用基于Windows的计算机进行日常工作或娱乐时,您可能会遇到一个错误消息:“无法启动此程序,因为计算机中丢失msvcp120.dll。”这样的提示通常在尝试启动某些程序或游戏时弹出,导致应用无法正常运行。这个问题通常与系统中的某个…

CSS3页面布局-三栏-固定宽度布局

布局的基本概念 多栏布局三种基本实现方案:固定宽度,流动,弹性。 固定宽度布局:大小不会随用户调整浏览器窗口大小。 一版960-1100,960常见,可以被3,4,5,6,8,10,12,16整除。 流动布局:大小会随用户调整…

数据结构——链式二叉树的实现与分治编程思维(c语言实现)

目录 前言: 1.前置说明 2.链式二叉树的遍历 2.1 前序,中序及后续遍历 2.2 前序遍历实现 2.3 中序遍历实现 2.4 后续遍历实现 3.结点个数以及高度等 3.1 结点个数 3.2 结点高度 3.3 叶子结点的个数 前言: 在之前的学习中&…

【图解秒杀系列】秒杀技术点——多级缓存、分层过滤

【图解秒杀系列】秒杀技术点——多级缓存、分层过滤 多级缓存本地缓存分布式缓存 分层过滤 多级缓存 多级缓存在秒杀系统中是非常重要的一个技术点,是应对秒杀场景瞬时高并发读请求的一种有效手段。通过在数据库前面加入多个缓存层,达到过滤掉大多数读请…

优惠券秒杀项目

一、添加优惠券的同时,将优惠券信息,以及用户列表放到redis中 Override Transactional public void addSeckillVoucher(Voucher voucher) {// 保存优惠券save(voucher);// 保存秒杀信息SeckillVoucher seckillVoucher new SeckillVoucher();seckillVou…

easyexcel--多sheet页导入导出

多sheet页导出 核心代码就是下图里面的,使用EasyExcel.writeSheet创建一个sheet,然后用excelWriter写入就行了,很简单 GetMapping("downloadMultiSheet")public void downloadMultiSheet(HttpServletResponse response) throws IOException {…

【Qt】输入类控件QDateTimeEdit

目录 输入类控件QDateTimeEdit 例子:实现日期计算器 输入类控件QDateTimeEdit QDate Edit作为日期的微调框 QTime Edit作为时间的微调框 QDateTimeEdit作为时间日期的微调框 下面主要讲解QDateTimeEdit: 核心属性 属性说明 dateTime 时间⽇期的值.…

【Hot100】LeetCode—101. 对称二叉树

目录 1- 思路借助队列 2- 实现⭐101. 对称二叉树——题解思路 3- ACM 实现 原题连接&#xff1a;101. 对称二叉树 1- 思路 借助队列 1- 创建队列&#xff1a;Queue<TreeNode> queue&#xff0c;初始化加入 root.left 和 root.right2- 判断逻辑&#xff1a;while(!queu…

软件开发者的首选:最佳Bug测试工具Top 10

本篇文章介绍了以下软件bug测试管理工具&#xff1a;PingCode、Worktile、Test360、禅道、码云Gitee、优云测试、Jira、GitHub、Axosoft、Bugzilla。 在开发过程中&#xff0c;Bug的管理往往是最让人头疼的问题之一。小问题积累起来不仅会拖延项目进度&#xff0c;还可能影响到…

如何优雅处理异步组件加载:Vue 3 的 Suspense 特性

在日常开发中&#xff0c;我们可能会遇到网络不佳或内容加载时间较长的情况。如果当前页面没有任何内容提示&#xff0c;用户的体验非常糟糕&#xff0c;可能会反复刷新以便加载成功。因此&#xff0c;我们需要给用户提供一个加载中的效果&#xff0c;告知用户“我在努力加载中…

基于单片机的人体健康监测系统的设计

本设计以STM32F103C8T6单片机作为主控&#xff0c;通过MAX30102采集心率、血氧值&#xff0c;通过MSP20血压采集模块检测血压值&#xff0c;通过MLX90614红外体温采集模块检测体温值。OLED屏可以显示以上检测的信息&#xff0c;并可以通过蓝牙模块将信息发送给手机APP。当检测值…

利用VirtualBox安装CentOS系统

博主这次用VirtualBox虚拟机安装CentOS系统。无论是大小型项目都是要发布到云主机上面&#xff0c;必然要用到Linux系统&#xff0c;有的人的本地电脑硬件配置不高&#xff0c;没有办法运行数据库集群&#xff0c;所以只能借助云主机。毕竟云主机也是Linux系统&#xff0c;大家…

大数据-92 Spark 集群 SparkRDD 原理 Standalone详解 ShuffleV1V2详解 RDD编程优化

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

OZON什么产品好卖丨OZON婴儿用具产品

Top1 摇铃 Деревянная стойка тренажер Монтессори для мобилей и игрушек для новорожденных / развивающая дуга 商品id&#xff1a;1557614414 月销量&#xff1a;707 OZON婴儿用具…

Leetcode-day31-01背包问题

46. 携带研究材料 1.dp数组代表的是什么&#xff1f; 这里的dp数组是一个二维数组&#xff0c;dp[i][j]是从前i个物品中任选放入容量j内的最大价值。 2.递推公式。 不放物品i&#xff1a;由dp[i - 1][j]推出&#xff0c;即背包容量为j&#xff0c;里面不放物品i的最大价值&am…

uniapp检测手机是否打开定位权限Vue3-直接复制粘贴

安卓示例&#xff1a; 苹果示例&#xff1a; 代码实现&#xff08;vue3写法&#xff09;&#xff1a; const checkGPS ()>{console.log(开始监听GPS状态);let system uni.getSystemInfoSync(); // 获取系统信息if (system.platform android) { // 判断平台var context …

全国上市公司网络安全风险指数(2001-2023年)

数据来源&#xff1a;本数据参考耿勇老师等&#xff08;2024&#xff09;做法采集了2001-2023年的上市公司年报&#xff0c;所有年报均来自于深交所和上交所官方网站&#xff0c;通过对上市公司的年报进行精读&#xff0c;提取出包括网络安全、网络攻击等在内的39个关键词构成企…

牛客笔试小题

目录 牛客.小红取数 牛客.哈夫曼编码​编辑 牛客.字符编码(上一道题的资料) 牛客.最小的完全平方数 牛客.小红取数 01背包问题:在满足总和必须为k的倍数的情况下&#xff0c;选择最大的总和 1.状态表示: dp[i][j]:表示从前面i个数字中挑选&#xff0c;总和%k等于j时候,最大的…

微服务——远程调用

为什么需要远程调用&#xff1f; 在微服务架构中&#xff0c;每个服务都是独立部署和运行的&#xff0c;它们之间需要相互协作以完成复杂的业务逻辑。因此&#xff0c;远程调用成为微服务之间通信的主要方式。通过远程调用&#xff0c;一个服务可以请求另一个服务执行某些操作或…