[nginx源码分析]配置解析1

整个配置解析主要是函数ngx_init_cycle(&init_cycle)进行处理。

ngx_init_cycle(&init_cycle)

ngx_time_update()//时间更新,也是在main函数里面讲过

	/*
 	* 通过加锁和解锁,来更新如下时间
 	   ngx_cached_time = tp;
 	   ngx_cached_http_time.data = p0;
 	   ngx_cached_err_log_time.data = p1;
 	   ngx_cached_http_log_time.data = p2;
 	   ngx_cached_http_log_iso8601.data = p3;
 	 */

log = old_cycle->log;//错误日志对象

pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE,log);//分配一块16k的内存池,第一个节点大约是16k,如果新增小块内存节点,那么该节点最大为4095


cycle->pool = pool;
cycle->log = log;
cycle->new_log.log_level = NGX_LOG_ERR;
cycle->conf_prefix;						//设置配置文件dir
cycle->prefix;							//设置运行环境dir
cycle->conf_file;						//设置配置文件绝对路径
cycle->conf_param;						//保存参数
cycle->pathes;							//路径数组
cycle->open_files;						//分配打开的文件描述符,其中这个结构是一
个链表,每个链表节点都有一个n个size的
cycle->shared_memory;					//分配n个共享内存节点,这个是一个list,
每个节点都存在n个ngx_shm_zone_t结构,通过next指向链表后面的节点。
cycle->listening;						//listening数组

cycle->conf_ctx = ngx_pcalloc(pool, ngx_max_module*sizeof(void*));

为cycle分配ngx_max_module个上下文指针

首先创建核心模块的上下文结构,保存在cycle->conf_ctx相应的结构里面

核心模块如下:

NGX_CORE_MODULE						index
Ngx_core_module							0
Ngx_errlog_module						1
Ngx_reg_module							6
Ngx_events_module						3
Ngx_http_module							7

核心代码

     for (i = 0; ngx_modules[i]; i++) {
         if (ngx_modules[i]->type != NGX_CORE_MODULE) {
             continue;
         }

         module = ngx_modules[i]->ctx;                                                                                                                             

         if (module->create_conf) {
             rv = module->create_conf(cycle);
             if (rv == NULL) {
                 ngx_destroy_pool(pool);
                 return NULL;
             }
             cycle->conf_ctx[ngx_modules[i]->index] = rv;
         }
     }

nginx首先创建NGX_CORE_MODULE是为了创建后面的模块上下文做铺垫,也就是

NGX_CORE_MODULE是其他模块的基础,如下:

其中Ngx_errlog_module、ngx_events_module、ngx_http_module模块都没有create_conf

方法,是根据用户的conf实际动态的进行创建。

     conf.args = ngx_array_create(pool, 10, sizeof(ngx_str_t));
      if (conf.args == NULL) {
          ngx_destroy_pool(pool);
          return NULL;
      }

      conf.temp_pool = ngx_create_pool(NGX_CYCLE_POOL_SIZE, log);
      if (conf.temp_pool == NULL) {
          ngx_destroy_pool(pool);
          return NULL;
      }

      conf.ctx = cycle->conf_ctx;
      conf.cycle = cycle;
      conf.pool = pool;
      conf.log = log;
      conf.module_type = NGX_CORE_MODULE;
      conf.cmd_type = NGX_MAIN_CONF;

为conf创建参数,用于保存配置文件的用户配置key和value,同时创建temp_pool内

存池,conf->ctx指向cycle->conf_ctx,保存cycle、pool、log,设置模块类型和命令类型,

开始解析主配置文件变量。

解析配置文件的过程主要是ngx_conf_parse进行间接递归调用,主要分为main作用域   、event作用域、http作用域、server作用域、location作用域,然后接下来就进行分析。

在解析过程中,对配置文件(nginx.conf)分为三类:

enum{
	parse_file = 0,	//解析文件,比如nginx.conf 还有include文件
	parse_block,	//解析块,比如http{}块
	parse_param	//解析参数	比如deamon off
}

进入ngx_conf_parse函数,根据是否是解析文件、解析块、解析参数,来设置不同的值,然后进入ngx_conf_read_token,这个函数,主要是读取文件,然后设置一些旗变量,保存用户配置到conf->args里面,其中在解析配置文件(nginx.conf)的时候使用一个buffer内存,主要读取文件,然后解析buffer,解析过程是流式,如果buffer后面还有未解析完,但是没有遇到分号or大括号之类的,就会把未解析完移动到buffer的头部,然后在继续读文件,进行解析,每调用玩一次ngx_conf_read_token就会解析完一个命令,如果配置文件配置有问题,就会报错。解析完一个用户的设置后,保存在conf->args数组中。如果发现cf->handler有值,就调用cf->handler进行回调处理(一般处理mine.types文件),如果cf->handler为空,那么就调用ngx_conf_handler,遍历每一个模块的cmd,来case,找到该命令,并且调用命令的set回调方法,如果cmd是一个key
value的变量设置,给相应模块变量设置完后,就调用ngx_conf_read_token,如果是一个块的key,比如http、event、location,他们的回调函数(cmd->set)首先是创建上下文结构变量,然后间接递归ngx_conf_parse,当然就会设置不同的上下文。

时间: 2024-10-08 16:36:04

[nginx源码分析]配置解析1的相关文章

[nginx源码分析]配置解析(http作用域)

分析完events后,开始分析http.sever.location模块. http上下文主要是创建三个用于保存每一个模块设置的变量结构,每个模块都可以保存变量到http三个数组指针中(main.server.location),每个模块的索引是模块的ctx_index变量指定在三个数组中的位置 核心代码: ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_conf_ctx_t)); //首先分配一个http上下文变量,里面是指针的指针,因为后面分配数组都是

nginx源码分析--配置信息的继承&合并

这里只讲述http{}模块下的配置: 在ngx_http_block()函数内(这个函数别调用时在ngx_inti_cycle内的ngx_conf_parse函数,这个函数遇到http命令时 回调ngx_http_block,开启http{}配置块的解读工作),针对每一个http模块,调用init_conf之后,有调用了ngx_http_merge_servers().这是为何! 首先明确几点:一个http{}配置块内可以包含多个server{}配置块,每个server{}配置块可以包含多个lo

nginx源码分析--nginx模块解析

nginx的模块非常之多,可以认为所有代码都是以模块的形式组织,这包括核心模块和功能模块,针对不同的应用场合,并非所有的功能模块都要被用到,附录A给出的是默认configure(即简单的http服务器应用)下被连接的模块,这里虽说是模块连接,但nginx不会像apache或lighttpd那样在编译时生成so动态库而在程序执行时再进行动态加载,nginx模块源文件会在生成nginx时就直接被编译到其二进制执行文件中,所以如果要选用不同的功能模块,必须对nginx做重新配置和编译.对于功能模块的选

nginx源码分析--nginx外部信号 命令参数

nginx命令行参数 不像许多其他软件系统,Nginx 仅有几个命令行参数,完全通过配置文件来配置 -c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的. -t 不运行,而仅仅测试配置文件.nginx 将检查配置文件的语法的正确性,并尝试打开配置文件中所引用到的文件. -v 显示 nginx 的版本. -V 显示 nginx 的版本,编译器版本和配置参数. nginx控制信号 可以使用信号系统来控制主进程.默认,nginx 将其主进程的 pid 写入到 /u

nginx源码分析--监听套接字的创建 套接字的监听 HTTP请求创建连接

作为一个web服务器,那么肯定是有监听套接字的,这个监听套接字是用于接收HTTP请求的,这个监听套接字的创建是根据配置文件的内容来创建的,在nginx.conf文件中有多少个地址就需要创建多少个监听套接字.这里不说各个结构体的构造 只说大体情况! 1).首先在main函数中调用了ngx_init_cycle()函数,在这个函数的最后调用了ngx_open_listening_sockets函数,这个函数负责将创建的监听套接字进行套接字选项的设置(比如非阻塞.接受发送的缓冲区.绑定.监听处理) 2

Nginx源码分析:3张图看懂启动及进程工作原理

编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」.   导读:很多工程师及架构师都希望了解及掌握高性能服务器开发,阅读优秀源代码是一种有效的方式,nginx 是业界知名的高性能 Web 服务器实现,如何有效的阅读及理解 nginx?本文用图解的方式帮助大家来更好的阅读及理解 nginx 关键环节的实现.   陈科,十年行业从业经验,曾在浙江电信.阿里巴巴.华为.五八同城任开发工程及架构师等职,目前负责河狸

Nginx源码分析 - Nginx启动以及IOCP模型

Nginx 源码分析 - Nginx启动以及IOCP模型 版本及平台信息 本文档针对Nginx1.11.7版本,分析Windows下的相关代码,虽然服务器可能用linux更多,但是windows平台下的代码也基本相似 ,另外windows的IOCP完成端口,异步IO模型非常优秀,很值得一看. Nginx启动 曾经有朋友问我,面对一个大项目的源代码,应该从何读起呢?我给他举了一个例子,我们学校大一大二是在紫金港校区,到了 大三搬到玉泉校区,但是大一的时候也会有时候有事情要去玉泉办.偶尔会去玉泉,但

nginx源码分析之模块初始化

在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要通过结合源码来分析模块的初始化过程. 稍微了解nginx的人都知道nginx是高度模块化的,各个功能都封装在模块中,而各个模块的初始化则是根据配置文件来进行的,下面我们会看到nginx边解析配置文件中的指令,边初始化指令所属的模块,指令其实就是指示怎样初始化模块的. 模块初始化框架 模块的初始化主要

nginx源码分析之网络初始化

nginx作为一个高性能的HTTP服务器,网络的处理是其核心,了解网络的初始化有助于加深对nginx网络处理的了解,本文主要通过nginx的源代码来分析其网络初始化. 从配置文件中读取初始化信息 与网络有关的配置命令主要有两个:listen和sever_name.首先先了解这两个命令的用法. listen listen命令设置nginx监听地址,nginx从这里接受请求.对于IP协议,这个地址就是address和port:对于UNIX域套接字协议,这个地址就是path. 一条listen指令只能