深入理解nginx http响应限速功能

2024-05-04 14:12

本文主要是介绍深入理解nginx http响应限速功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

  • 1. 引言
  • 2. 配置参数
    • 2.1 limit_rate 配置指令
    • 2.2 limit_rate_after 配置指令
    • 2.3 其他限速配置
  • 3. 源码分析

1. 引言

  在现代互联网应用中,服务器的性能和响应速度是至关重要的。为了保证服务器的稳定性和可靠性,限制客户端对服务器的访问速度是一项重要的任务。而nginx 是一款高性能的 Web 服务器和反向代理服务器,提供了丰富的功能来管理和控制客户端请求。其中,HTTP 响应限速功能就是是一种有效的方式,可以限制服务器端对客户端的响应速度,以避免服务器在运行过程中因为部分客户端占用过多的资源而导致网络和服务器负载过高,而引起服务的不稳定的问题。
  本文首先介绍了如何进行nginx配置来启用限速功能,然后通过深入源码来详细分析nginx http响应限速的实现原理,让大家对nginx的限速的实现原理有一个完整的认识。

2. 配置参数

  和响应限速有关的主要配置参数一共有两个,分别是limite_rate和limit_rate_after。

2.1 limit_rate 配置指令


语  法:	   limit_rate rate;
默认值:     	limit_rate 0;
上下文:	   http, server, location, if in location

  本条配置指令用来限制响应传输速率,单位为每秒字节数,如果设置为0表示禁用限速功能。这个限制是对每个请求来说的(而不是对每个客户端来限制的),也就是说如果同一个客户端同时开启了两个链接,那么总的最大响应速率降是这个限制速率的两倍。

  配置的参数值可以支持变量(从1.17.0版本开始)。这可能在限制的速率值依赖于某个条件的常见下面显得非常有用,譬如:


map $slow $rate {1     4k;2     8k;
}limit_rate $rate;

  上例利用map模块,将$slow变量的值映射为$rate变量的值,譬如$slow变量为1,那么映射出$rate为4k。这样子,limit_rate就可以根据$slow的值来设置最终要限制的响应速率了。
  这样子,结合map模块的功能,我们完全可以让限速功能变得得更加灵活,譬如根据http header的某个值来映射速率,根据请求的url或者域名来限制速率等等,这里就不在赘述了。

2.2 limit_rate_after 配置指令

语  法:	    limit_rate_after size;
默认值:	limit_rate_after 0;
上下文:	    http, server, location, if in location
备  注:本条配置指令从0.8.0版本开始生效。

  本条配置指令用来设置在给客户端发送的响应的字节数超过指定的值以后才开始限速。和limit_rate配置指令一样,从1.17.0版本开始,可以支持变量方式配置。
  这样指令在流媒体播放的场景下面比较有用,为了支持播放器能够尽量缩短播放前的加载时间,我们就需要在刚开始的时候尽可能快速地将视频文件的头部发送给客户端;而等到播放器满足播放条件开始播放的时候,我们又不太希望播放器加载得太快从而浪费服务器的资源和网络资源,所以需要限制客户端的下载速度到某一个合理的值,只要保证播放器能够流畅播放即可。
  而limit_rate_after的配置指令正好满足的这个场景的需求。

2.3 其他限速配置

  nginx还可以支持通过设置$limit_rate变量参数来对响应速度进行限制,这样就可以在nginx的运行过程中,由脚本或者插件动态设置响应速率,这样子限速逻辑更加灵活了。不过,从1.17.0版本开始,nginx官方不推荐使用这个方法。

  nginx还支持上游服务器通过X-Accel-Limit-Rateheader头来告诉nginx对本次响应进行限速多少的功能。这里不再赘述。

3. 源码分析

  nginx http的限速功能是通过ngx_http_write_filter函数来实现的。ngx_http_write_filter函数是 nginx 在处理 HTTP 请求时的一个重要函数,它的主要作用是将响应数据写入到客户端的网络连接。具体来说,ngx_http_write_filter 函数执行以下关键任务:

  • 确定发送响应数据的方式:根据客户端连接的类型(例如普通连接、SSL 连接等),ngx_http_write_filter 函数确定使用哪种方式将响应数据发送给客户端。这包括直接发送数据、缓存数据再发送或者将数据写入到发送缓冲区等。

  • 处理发送缓冲区:ngx_http_write_filter 函数会将响应数据写入到发送缓冲区。发送缓冲区是一个用于临时存储将要发送给客户端的数据的内存区域。nginx 使用发送缓冲区来提高发送效率,避免每次发送数据都需要进行系统调用。

  • 调用操作系统的网络发送函数:当发送缓冲区中的数据达到一定大小或者达到一定的时间间隔时,ngx_http_write_filter 函数会调用操作系统提供的网络发送函数,将数据从发送缓冲区发送到客户端的网络连接中。

  • 处理发送过程中的错误:在发送响应数据的过程中,可能会发生一些错误,例如网络连接中断、客户端关闭连接等。ngx_http_write_filter 函数会检测并处理这些错误情况,确保响应数据能够正确地发送给客户端。

   下图给出了ngx_http_writer_filter实现的大致流程图:

在这里插入图片描述

  限速原理的重点逻辑就是下面两个公式:

limit = (off_t) r->limit_rate * (ngx_time() - r->start_sec + 1)- (c->sent - r->limit_rate_after);delay = (ngx_msec_t) (- limit * 1000 / r->limit_rate + 1);

  其中limit就是到目前为止按照设置的限速速率计算本次最多可以发送多少字节
  如果limit<=0,表示本次已经没有发送的额度了,需要进行延时发送。在这个时候就需要计算延时发送的延时时长,用到的就是delay变量了,该变量很好理解,就是到目前已经超额发送的字节数/允许发送的速率,得到延时的毫秒数,然后调用ngx_add_timer设置定时器进行延时处理。

  对照以上流程图和相关解释,ngx_http_write_filter的主要实现逻辑包括限速逻辑,我们有理由相信不难理解把握了,大家有兴趣可以自行阅读源码。

这篇关于深入理解nginx http响应限速功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/959388

相关文章

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现

Android我的二维码扫描功能发展史(完整)

最近在研究下二维码扫描功能,跟据从网上查阅的资料到自己勉强已实现扫描功能来一一介绍我的二维码扫描功能实现的发展历程: 首页通过网络搜索发现做android二维码扫描功能看去都是基于google的ZXing项目开发。 2、搜索怎么使用ZXing实现自己的二维码扫描:从网上下载ZXing-2.2.zip以及core-2.2-source.jar文件,分别解压两个文件。然后把.jar解压出来的整个c

回调的简单理解

之前一直不太明白回调的用法,现在简单的理解下 就按这张slidingmenu来说,主界面为Activity界面,而旁边的菜单为fragment界面。1.现在通过主界面的slidingmenu按钮来点开旁边的菜单功能并且选中”区县“选项(到这里就可以理解为A类调用B类里面的c方法)。2.通过触发“区县”的选项使得主界面跳转到“区县”相关的新闻列表界面中(到这里就可以理解为B类调用A类中的d方法

如何理解redis是单线程的

写在文章开头 在面试时我们经常会问到这样一道题 你刚刚说redis是单线程的,那你能不能告诉我它是如何基于单个线程完成指令接收与连接接入的? 这时候我们经常会得到沉默,所以对于这道题,笔者会直接通过3.0.0源码分析的角度来剖析一下redis单线程的设计与实现。 Hi,我是 sharkChili ,是个不断在硬核技术上作死的 java coder ,是 CSDN的博客专家 ,也是开源

MySQL理解-下载-安装

MySQL理解: mysql:是一种关系型数据库管理系统。 下载: 进入官网MySQLhttps://www.mysql.com/  找到download 滑动到最下方:有一个开源社区版的链接地址: 然后就下载完成了 安装: 双击: 一直next 一直next这一步: 一直next到这里: 等待加载完成: 一直下一步到这里

开启青龙 Ninja 扫码功能失效后修改成手动填写CK功能【修正Ninja拉库地址】

国内:进入容器docker exec -it qinglong bash #获取ninjagit clone -b main https://ghproxy.com/https://github.com/wjx0428/ninja.git /ql/ninja#安装cd /ql/ninja/backend && pnpm install cp .env.example .env

PyTorch模型_trace实战:深入理解与应用

pytorch使用trace模型 1、使用trace生成torchscript模型2、使用trace的模型预测 1、使用trace生成torchscript模型 def save_trace(model, input, save_path):traced_script_model = torch.jit.trace(model, input)<

【机器学习】半监督学习可以实现什么功能?

目录 一、什么是机器学习二、半监督学习算法介绍三、半监督学习算法的应用场景四、半监督学习可以实现什么功能? 一、什么是机器学习 机器学习是一种人工智能技术,它使计算机系统能够从数据中学习并做出预测或决策,而无需明确编程。它涉及到使用算法和统计模型来分析大量数据,识别其中的模式和关系,并利用这些信息来预测未来事件或做出决策。机器学习可以应用于各种领域,包括图像识别、自然语言

BD错误集锦6——【IDEA报错】tomcat server功能无效,报错Java EE: EJB, JPA, Servlets

在网上查找原因,发现是非法关闭IDEA导致的。 Open Settings | Plugns and enable it. 在设置中enable JAVA EE和tomcat server即可。 参考: https://stackoverflow.com/questions/43607642/intellij-idea-plugin-errorproblems-found-loadin