• 【Nginx】HTTP配置模型


    当Nginx检測到配置文件里存在配置块http{}时。会建立一个ngx_http_conf_ctx_t结构体,该结构体定义例如以下:

    typedef struct {
        void        **main_conf;    // 每一个指针元素指向全部由HTTP模块的create_main_conf方法产生的结构体
        void        **srv_conf;     // 每一个指针元素指向全部由HTTP模块的create_srv_conf方法产生的结构体
        void        **loc_conf;     // 每一个指针元素指向全部由HTTP模块的create_loc_conf方法产生的结构体
    } ngx_http_conf_ctx_t;


    详细来说,框架代码在遇到http{}时会调用核心模块ngx_http_module(HTTP框架的一部分)中解析配置项的ngx_http_block方法,该方法的关于生成和配置ngx_http_conf_ctx_t结构体的过程大致例如以下,代码位于ngx_http.c中:
    ngx_http_conf_ctx_t  *ctx;     // 定义一个该结构体的指针
     
    ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t));     // 分配该结构体空间
    
    ctx->main_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);     // 分配数组存放指针
    ctx->srv_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);      // 分配数组存放指针
    ctx->loc_conf = ngx_pcalloc(cf->pool, sizeof(void *) * ngx_http_max_module);      // 分配数组存放指针
     
    for (m = 0; ngx_modules[m]; m++)
    {
        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
            continue;
        }
     
        module = ngx_modules[m]->ctx;
        mi = ngx_modules[m]->ctx_index;
     
        if (module->create_main_conf)
        {
            /* 依次调用全部HTTP模块的create_main_conf方法
             * 产生的结构体指针放入上面分配了空间的main_conf指针数组中
             */
            ctx->main_conf[mi] = module->create_main_conf(cf);
            if (ctx->main_conf[mi] == NULL)
            {
                return NGX_CONF_ERROR;
            }
        }
     
        if (module->create_srv_conf)
        {
            /* 依次调用全部HTTP模块的create_srv_conf方法
             * 产生的结构体指针放入上面分配了空间的srv_conf指针数组中
             */
            ctx->srv_conf[mi] = module->create_srv_conf(cf);
            if (ctx->srv_conf[mi] == NULL)
            {
                 return NGX_CONF_ERROR;
            }
        }
     
        if (module->create_loc_conf)
        {
            /* 依次调用全部HTTP模块的create_loc_conf方法
             * 产生的结构体指针放入上面分配了空间的loc_conf指针数组中
             */
            ctx->loc_conf[mi] = module->create_loc_conf(cf);
            if (ctx->loc_conf[mi] == NULL)
            {
                return NGX_CONF_ERROR;
            }
        }
    }
    


    server{}和location{}和http{}相似:
    • 当遇到server{}配置块时,建立ngx_http_conf_ctx_t结构体。main_conf成员指向父配置块所相应的ngx_http_conf_ctx_t结构体,srv_conf成员和loc_conf成员存储HTTP模块通过create_srv_conf和create_loc_conf方法产生的配置结构体指针。
    • 当遇到location{}配置块时,建立ngx_http_conf_ctx_t结构体,main_conf成员指向父配置块相应ngx_http_conf_ctx_t结构体。srv_conf成员指向父配置块ngx_http_conf_ctx_t结构体的srv_conf元素。loc_conf存储HTTP模块create_loc_conf方法产生的配置结构体指针。
    三个ngx_http_conf_ctx_t结构体分别相应http{}、server{}、location{},它们之间的关系用下图能够清晰的说明:


    以下介绍解析HTTP配置的大致流程:
    1. Nginx进程主循环调用配置文件解析器解析nginx.conf配置文件。
    2. 配置文件解析器发现http{},启动HTTP框架,也就是核心模块ngx_http_module。

    3. 核心模块调用ngx_command_t中的set回调函数,也就是ngx_http_block方法。

    4. 初始化全部HTTP模块的序号。分配一个ngx_http_conf_ctx_t结构体并初始化三个数组。

    5. 调用每一个HTTP模块的create_main_conf、create_srv_conf、create_loc_conf方法分配存储配置项參数的结构体,返回的指针保存在ngx_http_conf_ctx_t结构体中。
    6. 调用每一个HTTP模块的preconfiguration方法。

    7. 配置文件解析器检測到一个配置项后。遍历全部HTTP模块的ngx_command_t数组,看有没有可以和配置项名称匹配的ngx_command_t结构体,有则调用ngx_command_t结构中的set方法来处理配置项。

    8. 配置文件解析器继续检測配置项,遇到server{}或location{}则以类似的方法递归解析块中的配置项,只是此时负责解析配置项的模块变成了ngx_http_core_module,方法在上面已经具体说明了。

    9. 配置文件解析器解析到http{}尾端,返回HTTP框架ngx_http_module。
    10. 调用merge_srv_conf和merge_loc_conf等方法合并配置项结构体。

    11. HTTP框架处理完http配置项,ngx_command_t的set回调方法返回。
    12. 配置文件解析器返回Nginx主循环。Nginx进程启动Web服务器。
    參考:
    《深入理解Nginx》 P140-P143.
  • 相关阅读:
    在X++中编译并执行C#脚本
    XML的序列化读取方式
    在Dynamics AX 2009中调用Crystal Reports
    AspDotNetStorefront中事件处理页面开发的注意事项
    WCF服务开发中的SecurityNegotiationException异常
    Visual Studio 2010 RC版发布
    初探.NET 4.0中的Entity Framework
    入学十年
    HP dv1606tn 笔记本安装Windows 7经验一则
    在VS.NET2008中使用并发布Crystal Reports ActiveX组件
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7243842.html
Copyright © 2020-2023  润新知