nginx 获取配置的宏执行过程1

来源:互联网 发布:js面向对象和原型 编辑:程序博客网 时间:2024/06/06 15:43

nginx中获取配置通常我们使用以下宏


#define ngx_http_conf_get_module_main_conf(cf, module)                        \
    ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]
#define ngx_http_conf_get_module_srv_conf(cf, module)                         \
    ((ngx_http_conf_ctx_t *) cf->ctx)->srv_conf[module.ctx_index]
#define ngx_http_conf_get_module_loc_conf(cf, module)                         \
    ((ngx_http_conf_ctx_t *) cf->ctx)->loc_conf[module.ctx_index]


#define ngx_http_get_module_main_conf(r, module)                             \
    (r)->main_conf[module.ctx_index]
#define ngx_http_get_module_srv_conf(r, module)  (r)->srv_conf[module.ctx_index]
#define ngx_http_get_module_loc_conf(r, module)  (r)->loc_conf[module.ctx_index]


对于第一种我们通常是在解析配置的过程中使用,

#define ngx_http_conf_get_module_main_conf(cf, module)   ((ngx_http_conf_ctx_t *) cf->ctx)->main_conf[module.ctx_index]

其中cf->ctx即为在解析过程中(http,server,location)创建的,分别指向main_conf中各个模块的指针,这种方法调用比较容易理解。


对于第二种就比较复杂了
#define ngx_http_get_module_main_conf(r, module)                             (r)->main_conf[module.ctx_index]

首先我们需要知道r->main_conf指向的是哪里?

在ngx_http_create_request函数中分别对***_conf赋值

    r->main_conf = hc->conf_ctx->main_conf;
    r->srv_conf = hc->conf_ctx->srv_conf;
    r->loc_conf = hc->conf_ctx->loc_conf;

那再往回推,hc->conf_ctx又指向的是哪里呢?

在ngx_http_init_connection函数中hc->conf_ctx = hc->addr_conf->default_server->ctx;

再往上看可以看到 port = c->listening->servers; addr = port->addrs; hc->addr_conf = &addr[0].conf;

再往上看ngx_event_process_init中ls = cycle->listening.elts;  c->listening = &ls[i];

那cycle->listening又是怎么来的?


需要先说下执行http的set函数时,最后一个步骤是ngx_http_optimize_servers,

该函数即是对于server管理的入口函数

 /* optimize the lists of ports, addresses and server names */

    if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) {
        return NGX_CONF_ERROR;
    }

第一个参数cf为main函数传递下来的cf,不过cf->ctx为http_block函数申请的空间

第二个参数cmcf即为main_conf中core_module的指针,

第三个参数为cmcf->ports

该函数的处理流程是:

会遍历cmcf->ports,那对于cmcf->ports是什么时候创建以及赋值的呢?

首先看下listen的相关处理

listen关键字的处理函数为:ngx_http_core_listen

函数调用为:ngx_http_core_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)

参数分别为:

cf,listen是在server里面,所以cf的main_conf以及srv_conf都为server里面创建的

cmd即为listen关键字的cmd

conf为server里面创建的srv_conf首地址,listen的conf为NGX_HTTP_SRV_CONF_OFFSET

中间就是解析listen后面的一些选项,接下来调用ngx_http_add_listen函数

函数调用形式为ngx_http_add_listen(cf, cscf, &lsopt) 

cf和上面的cf

cscf和conf一样

lsopt为listen后面携带的选项解析存储的值

该函数执行流程为:

获取在server层级的main_conf(同时也是http层级的main),如果是第一次则cmcf->ports分配空间

调用ngx_http_add_address,

如果port已经add过了 ,调用方式为:ngx_http_add_addresses(cf, cscf, &port[i], lsopt)

第一个参数cf没有做过修改,

第二个参数cscf指向的是srv_config

第三个参数是已经设置了该端口的port地址

说明:cmcf->port是一个ngx_array_t类型的指针,它的elt是ngx_http_conf_port_t类型;

里面的port值保存的是port的数值,(最外层保存的是port数字,也就是说以监听端口做为最外层的唯一标识)

port里面的addrs同样也是一个ngx_http_array_t,它的elt是ngx_http_conf_addr_t。

第四个参数lsopt为传递过来的参数

如果port还没有add过,调用方式为:ngx_http_add_address(cf, cscf, port, lsopt)

第一个参数cf没有做过修改,

第二个参数cscf指向的是srv_config

第三个参数port为在cmcf->ports上面新添加的item,cmcf->ports为一个ngx_array_t类型

第四个参数lsopt为传递过来的参数

调用形式为ngx_http_add_address(cf, cscf, port, lsopt)

该函数主要是把lsopt里面的信息存放到port里面的addrs,addrs是一个ngx_array_t类型

addr = ngx_array_push(&port->addrs);

addr->servers.elts = NULL;

需要说明的是:addr->default_server = cscf;在port里面新添加的item的default_servers指向的是cscf,也就是server里面的ctx

接下来调用ngx_http_add_server(cf, cscf, addr)

把当前的cscf加入到addr->servers。



接下来继续回到ngx_http_optimize_servers函数

该函数会遍历cmcf->ports,

遍历每个port的addrs,nginx官方给的注释是:检查和defaultserver有无相同配置ip和端口。调用ngx_http_server_names函数

该函数的调用方式为:ngx_http_server_names(cf, cmcf, &addr[a])

第一个参数cf,cf->ctx指向的是server里面创建的ctx

第二个参数cmcf,指向的是main_conf

第三个参数&addr[a],指向的是cmcf->port->addrs里面的每个addr

该函数主要就是对addr里面的一些变量进行初始化以及对regex赋值

接着调用ngx_http_init_listening函数

该函数的调用形式为:ngx_http_init_listening(cf, &port[p])

第二个参数即为当前的port

调用ngx_http_add_listening函数,把每个port里面的addr加进去,在该函数里面调用了ngx_create_listening函数,ngx_create_listening函数里面会把当前addr里面的信息添加到cf->cycle->listening,这就是添加listening的地方。

接着申请了一块ngx_http_port_t空间,通过调用ngx_http_add_addrs把addr添加进hport的addrs里面,调用ngx_clone_listening为每个进程添加一个ls,什么时候用还不清楚。


那到目前为止,文章最开始的问题都解决了,

也就是在调用ngx_http_create_request之前,r->main_conf,srv_conf,loc_conf都是指向的是server创建的,这个显然不是正确的,接下来怎么调整指向,另外一篇文章接着分析。



0 0
原创粉丝点击