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

上接 深入理解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,</

相关推荐

  1. 深入理解nginx请求限速模块[]

    2024-03-19 21:50:03       40 阅读
  2. 深入理解nginx mp4流媒体模块[]

    2024-03-19 21:50:03       39 阅读
  3. 深入理解nginxuserid模块

    2024-03-19 21:50:03       38 阅读
  4. 深入理解nginx连接数限制模块[上]

    2024-03-19 21:50:03       41 阅读
  5. Nginx 对客户端请求限制

    2024-03-19 21:50:03       34 阅读
  6. 深入理解nginx mp4流媒体模块[中]

    2024-03-19 21:50:03       45 阅读
  7. 深入理解通用HTTP POST请求发送方法

    2024-03-19 21:50:03       59 阅读
  8. 深入理解python中subprocess模块

    2024-03-19 21:50:03       28 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-03-19 21:50:03       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-03-19 21:50:03       106 阅读
  3. 在Django里面运行非项目文件

    2024-03-19 21:50:03       87 阅读
  4. Python语言-面向对象

    2024-03-19 21:50:03       96 阅读

热门阅读

  1. Winform编程详解十八:ContextMenuStrip 右键菜单

    2024-03-19 21:50:03       41 阅读
  2. 新手leetcode 126周赛被拷打篇

    2024-03-19 21:50:03       43 阅读
  3. 安卓UI面试题 36-40

    2024-03-19 21:50:03       35 阅读
  4. 网络编程day4

    2024-03-19 21:50:03       45 阅读
  5. 关于前端的学习2

    2024-03-19 21:50:03       38 阅读
  6. 人生视角的双重镜像:喜剧与悲剧的辩证统一

    2024-03-19 21:50:03       41 阅读
  7. pytorch升级打怪(七)

    2024-03-19 21:50:03       40 阅读
  8. C语言 函数

    2024-03-19 21:50:03       45 阅读