深入理解nginx的请求限速模块[下]

2024-03-19 21:44

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

目录

  • 3. 源码分析
  • 3.1 配置指令
    • 3.1.1 limit_req_zone指令
      • 3.1.2 limit_req指令
      • 3.1.3 limit_req_dry_run指令
      • 3.1.4 limit_req_log_level指令
      • 3.1.5 limit_req_status指令
    • 3.2 模块初始化
    • 3.3 请求处理
      • 3.3.1 ngx_http_limit_req_handler
      • 3.3.1 ngx_http_limit_req_lookup
      • 3.3.2 ngx_http_limit_req_account

上接 深入理解nginx的请求限速模块[上]](https://blog.csdn.net/bluestn/article/details/136710631)

3. 源码分析

3.1 配置指令

3.1.1 limit_req_zone指令

  limit_req_zone指令的作用是定义一个共享内存区,用于在worker进程间共享限速的状态信息,因此请求限速模块的限速功能是服务器级别的,而不是单个worker进程级别的。其配置指令定义如下:

    { ngx_string("limit_req_zone"),NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE3,ngx_http_limit_req_zone,0,0,NULL },

   ngx_http_limit_req_zone函数的重要逻辑就是解析相应的参数,然后创建共享内存区:

static char *
ngx_http_limit_req_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
......ngx_http_limit_req_ctx_t *ctx;
......  ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_limit_req_ctx_t));解析配置指令
......ctx->rate = rate * 1000 / scale;/* 创建共享内存区 */shm_zone = ngx_shared_memory_add(cf, &name, size,&ngx_http_limit_req_module);if (shm_zone == NULL) {return NGX_CONF_ERROR;}if (shm_zone->data) {ctx = shm_zone->data;ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,"%V \"%V\" is already bound to key \"%V\"",&cmd->name, &name, &ctx->key.value);return NGX_CONF_ERROR;}shm_zone->init = ngx_http_limit_req_init_zone;shm_zone->data = ctx;     /* 设置共享内存区的上下文信息 */
}

3.1.2 limit_req指令

  limit_req指令则是开启请求限速功能,它需要引用前面limit_req_zone指令定义的共享内存区,并且指定允许的busrt突发值和delay值。其配置指令定义如下:

    { ngx_string("limit_req"),NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,ngx_http_limit_req,NGX_HTTP_LOC_CONF_OFFSET,0,NULL },
static char *
ngx_http_limit_req(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{ngx_http_limit_req_conf_t *lrcf = conf;ngx_http_limit_req_limit_t *limit, *limits;......解析配置指令/* 如果还没有创建限速规则数组,则创建一个 */	limits = lrcf->limits.elts;if (limits == NULL) {if (ngx_array_init(&lrcf->limits, cf->pool, 1,sizeof(ngx_http_limit_req_limit_t))!= NGX_OK){return NGX_CONF_ERROR;}}for (i = 0; i < lrcf->limits.nelts; i++) {if (shm_zone == limits[i].shm_zone) {return "is duplicate";}}/* 将当前limit_req指令添加到lrcf->limits数组中 */limit = ngx_array_push(&lrcf->limits);if (limit == NULL) {return NGX_CONF_ERROR;}limit->shm_zone = shm_zone;limit->burst = burst * 1000;    /* busrt的单位是r/ms,所以乘以1000 */limit->delay = delay * 1000;    /* delay的单位是r/ms,所以乘以1000 */return NGX_CONF_OK;
}

3.1.3 limit_req_dry_run指令

   该指令设置了一个开关,如果是on的话,如果发生了限流事件,只是在error日志中打印日志,而不是实际执行限流动作。这个指令主要用于开启限流操作前进行测试验证工作。配置指令定义如下:

    { ngx_string("limit_req_dry_run"),NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,ngx_conf_set_flag_slot,NGX_HTTP_LOC_CONF_OFFSET,offsetof(ngx_http_limit_req_conf_t, dry_run),NULL },

3.1.4 limit_req_log_level指令

  该指令设置了当发生限流事件的时候,在nginx的error日志中输出的日志的日志级别。配置指令定义如下:

    { ngx_string("limit_req_log_level"),NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,ngx_conf_set_enum_slot,NGX_HTTP_LOC_CONF_OFFSET,offsetof(ngx_http_limit_req_conf_t, limit_log_level),&ngx_http_limit_req_log_levels },

3.1.5 limit_req_status指令

  该指令设置了当发生限流事件的时候,nginx返回给客户端的响应码。

{ ngx_string("limit_req_status"),NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,ngx_conf_set_num_slot,</

这篇关于深入理解nginx的请求限速模块[下]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

解决systemctl reload nginx重启Nginx服务报错:Job for nginx.service invalid问题

《解决systemctlreloadnginx重启Nginx服务报错:Jobfornginx.serviceinvalid问题》文章描述了通过`systemctlstatusnginx.se... 目录systemctl reload nginx重启Nginx服务报错:Job for nginx.javas

一文带你理解Python中import机制与importlib的妙用

《一文带你理解Python中import机制与importlib的妙用》在Python编程的世界里,import语句是开发者最常用的工具之一,它就像一把钥匙,打开了通往各种功能和库的大门,下面就跟随小... 目录一、python import机制概述1.1 import语句的基本用法1.2 模块缓存机制1.

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

Java后端接口中提取请求头中的Cookie和Token的方法

《Java后端接口中提取请求头中的Cookie和Token的方法》在现代Web开发中,HTTP请求头(Header)是客户端与服务器之间传递信息的重要方式之一,本文将详细介绍如何在Java后端(以Sp... 目录引言1. 背景1.1 什么是 HTTP 请求头?1.2 为什么需要提取请求头?2. 使用 Spr

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

多模块的springboot项目发布指定模块的脚本方式

《多模块的springboot项目发布指定模块的脚本方式》该文章主要介绍了如何在多模块的SpringBoot项目中发布指定模块的脚本,作者原先的脚本会清理并编译所有模块,导致发布时间过长,通过简化脚本... 目录多模块的springboot项目发布指定模块的脚本1、不计成本地全部发布2、指定模块发布总结多模

centos7基于keepalived+nginx部署k8s1.26.0高可用集群

《centos7基于keepalived+nginx部署k8s1.26.0高可用集群》Kubernetes是一个开源的容器编排平台,用于自动化地部署、扩展和管理容器化应用程序,在生产环境中,为了确保集... 目录一、初始化(所有节点都执行)二、安装containerd(所有节点都执行)三、安装docker-

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规