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创建的,这个显然不是正确的,接下来怎么调整指向,另外一篇文章接着分析。
- nginx 获取配置的宏执行过程1
- nginx配置指令的执行顺序(1)转载子章亦春
- Nginx 配置指令的执行顺序
- 08-nginx网站的配置过程记录
- MongoDB+Nginx+Nginx-Gridfs的安装配置过程详解
- nginx事件模块执行过程
- Nginx+FastCgi配置过程
- Nginx 配置初始化过程
- nginx初探(1)--nginx安装过程详解、configure执行过程
- Struts2 配置 & 执行过程
- Nginx 配置指令的执行顺序(八)
- asp.net/C# 执行存储过程技术要点,获取Return返回值,解决“存储过程总返回-1”的问题
- nginx的执行模型
- nginx配置过程中碰到的编译错误
- nginx配置过程中碰到的编译错误
- nginx 模块架构 -- 配置文件的读取和配置过程
- Linux系统下安装配置Nginx的详细过程
- 记录nginx配置php7过程
- Predix 分析应用开发 1
- start with connect by prior 递归查询用法
- 简单记录下Android设计模式 ---个人笔记
- 打开新窗口的window.open使用方法以及最大化等问题解决方法汇总
- eclipse maven异常“Project configuration is not up-to-date with pom.xml
- nginx 获取配置的宏执行过程1
- Java安全架构____KeyGenerator(对称)秘钥生成工具详解
- Spring Boot 整合 Mybatis Annotation 注解的完整 Web 案例
- 存储过程循环+调用存储过程
- 产品相关的概念
- (0047)iOS开发之nil/Nil/NULL的区别
- Android Studio实现代码混淆
- 拟牛顿法
- Flutter进阶—创建有状态控件