IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    nginx模块开发(38)—limit_conn模块分析

    cjhust发表于 2013-09-25 15:51:29
    love 0

    1、知识百科

    该模块可以为一个地址指定的会话或者某些特殊情况限制并发连接数。nginx-1.4.2相对于nginx-1.2.0来说,limit_zone被建议成limit_conn_zone,新的指令处理方式和limit_req处理相似。

    Limit_req和limit_conn模块的主要区别是:limit_req用于限制每秒的请求数,limit_conn用于限制并发连接数。如果是网关产品,个人建议limit_req,因为limit_conn比较困难去衡量一个准确的值。limit_conn目前还没有发现适合它的场景。

    以下是nginx官方给的解释:

    (1)limit_req_zone:Limit frequency of connections from a client. This module allows you to limit the number of requests for a given session, or as a special case, with one address. Restriction done using leaky bucket.

    (2)limit_zone:Limit simultaneous connections from a client. This module makes it possible to limit the number of simultaneous connections for the assigned session or as a special case, from one address.

    按照字面的理解,limit_req_zone的功能是通过令牌桶原理来限制用户的连接频率。而 limit_conn_zone功能是限制一个客户端的并发连接数。一个是限制并发连接一个是限制连接频率。

    2、基础指令

    clip_image001[1]

    limit_conn_zone & limit_zone

    clip_image002

    limit_conn

    clip_image002[4]

    limit_conn_status

    指令功能:被封禁后返回的状态码,默认是503,设置的区间是[400,599]。

    3、数据结构

    clip_image002

    ngx_http_limit_conn_node_t

    typedef struct {

    u_char color;

    u_char len;

    u_short conn;

    u_char data[1];

    } ngx_http_limit_conn_node_t;

    ngx_http_limit_conn_cleanup_t

    typedef struct {

    ngx_shm_zone_t *shm_zone;

    ngx_rbtree_node_t *node;

    } ngx_http_limit_conn_cleanup_t;

    ngx_http_limit_conn_ctx_t

    typedef struct {

    ngx_rbtree_t *rbtree;

    ngx_int_t index; //变量的索引

    ngx_str_t var; //变量的值

    } ngx_http_limit_conn_ctx_t;

    结构功能:共享变量的数据。

    ngx_http_limit_conn_limit_t

    typedef struct {

    ngx_shm_zone_t *shm_zone; //shm_zone->data指向的是ctx

    ngx_uint_t conn;

    } ngx_http_limit_conn_limit_t;

    ngx_http_limit_conn_conf_t

    typedef struct {

    ngx_array_t limits; //多个规则

    ngx_uint_t log_level;

    ngx_uint_t status_code; //封禁后的返回码

    } ngx_http_limit_conn_conf_t;

    ngx_pool_cleanup_s

    struct ngx_pool_cleanup_s {

    ngx_pool_cleanup_pt handler;

    void *data; //存放数据

    ngx_pool_cleanup_t *next; //c->next=p->cleanup

    };

    ngx_pool_s

    struct ngx_pool_s {

    ngx_pool_data_t d;

    size_t max;

    ngx_pool_t *current;

    ngx_chain_t *chain;

    ngx_pool_large_t *large;

    ngx_pool_cleanup_t *cleanup;

    ngx_log_t *log;

    };

    4、操作函数

    ngx_http_limit_conn_create_conf(ngx_conf_t *cf)

    函数功能:分配空间。

    ngx_http_limit_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    函数功能:处理limit_zone指令,并创建指定共享内存的ctx。

    ngx_http_limit_conn_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    函数功能:处理limit_conn_zone指令,和ngx_http_limit_zone功能一样,新版本建议用此指令。

    ngx_http_limit_conn(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

    函数功能:处理limit_conn指令,实质是在某个作用域生效一个共享内存。

    ngx_http_limit_conn_merge_conf(ngx_conf_t *cf, void *parent, void *child)

    函数功能:合并上下文的值,status_code默认是503。

    ngx_http_limit_conn_init(ngx_conf_t *cf)

    函数功能:在NGX_HTTP_PREACCESS_PHASE阶段加上ngx_http_limit_conn_handler。

    ngx_http_limit_conn_init_zone(ngx_shm_zone_t *shm_zone, void *data)

    函数功能:处理new和old共享内存的数据。

    ngx_http_limit_conn_rbtree_insert_value(ngx_rbtree_node_t *temp,ngx_rbtree_node_t *node, ngx_rbtree_node_t *sentinel)

    函数功能:红黑树插入算法。

    ngx_http_limit_conn_lookup(ngx_rbtree_t *rbtree, ngx_http_variable_value_t *vv,uint32_t hash)

    函数功能:根据变量查找红黑树节点。

    ngx_http_limit_conn_handler(ngx_http_request_t *r)

    函数功能:根据变量值查找红黑树节点,如果节点不存在,则新建节点,如果存在,则比较与设定值的大小,超出则封禁。然后使用ngx_pool_cleanup_add添加回收机制,当我们调用ngx_destroy_pool()函数的时候,会进行回收相关的处理。

    ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)

    ngx_pool_cleanup_t *

    ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)

    {

    ngx_pool_cleanup_t *c;

    c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));

    if (c == NULL) {

    return NULL;

    }

    if (size) {

    c->data = ngx_palloc(p, size);

    if (c->data == NULL) {

    return NULL;

    }

    } else {

    c->data = NULL;

    }

    c->handler = NULL;

    c->next = p->cleanup;

    p->cleanup = c;

    ngx_log_debug1(NGX_LOG_DEBUG_ALLOC, p->log, 0, "add cleanup: %p", c);

    return c;

    }

    ngx_http_limit_conn_cleanup(void *data)

    函数功能:对lc->conn--,如果减为0,则删除红黑树节点。

    clip_image002[6]

    备注:每个请求被处理完,都会进入ngx_http_finalize_request->ngx_http_finalize_connection->(无论是否keepalive)-> ngx_http_free_request-> ngx_destroy_pool。

    ngx_http_limit_conn_cleanup_all(ngx_pool_t *pool)

    函数功能:如果连接数超过了设置,则调用该函数,并返回设置的status_code。

    5、参考资料

    http://hi.baidu.com/langwan/item/fdd3bf4a4ef66aefa4c06629

    http://storysky.blog.51cto.com/628458/642970/



沪ICP备19023445号-2号
友情链接