NGINX源码之:模块配置解析(1)

您所在的位置:网站首页 nginx源码解读 NGINX源码之:模块配置解析(1)

NGINX源码之:模块配置解析(1)

2024-01-01 06:29| 来源: 网络整理| 查看: 265

在NGINX的启动流程中,ngx_init_cycle是重点之一,而在ngx_init_cycle中,配置文件的解析又是重点中的重点。本文重点记录core域,event域,http域配置加载逻辑,主要记录个人重点关注的部分。

一、配置文件结构(命令类型) 配置文件每行(非注释行)的首个单词,当做是一个指令command(cmd);单行配置以分号为一行结束,以{}表示一个配置块,一个块中可以嵌套其他的块。 在这里插入图片描述

二、module基本静态配置 本文暂不做动态添加模块的相关笔记,NGINX初始提供一个默认的静态module数组,里面包含core域,events域,http域的默认模块列表。objs/ngx_modules.c 在这里插入图片描述 每个模块都用extern修饰,说明是引用的全局变量,比如ngx_core_module(nginx.c中定义): 在这里插入图片描述 基本每个模块都采用这种方式的配置,不同的是各种方法指针和配置conf结构体的不同。

command->type采用多个标识合并的方式如:NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, NGX_MAIN_CONF: 0001000000000000000000000000 NGX_DIRECT_CONF:0000000000010000000000000000 NGX_CONF_FLAG: 0000000000000000001000000000 type的值就为: 0001000000010000001000000000 然后用每个标识的值与type 进行&操作,就能判断type属不属于这个标识的类型。 如 type & NGX_CONF_FLAG = 0001000000010000001000000000 & 0000000000000000001000000000 = 0000000000000000001000000000(NGX_CONF_FLAG)

三、ngx_cycle_modules模块加载 在进入ngx_init_cycle方法前,会通过ngx_preinit_modules()方法,对每个模块的index和name赋值; 在ngx_preinit_modules进入ngx_conf_parse()前,会先再ngx_cycle_modules()中,将静态的module拷贝到cycle的modules中

四、core域module配置创建 完成ngx_cycle_modules拷贝之后,会对core域的模块优先创建配置ngx_cycle.c 231-246行 在这里插入图片描述 此时的配置结构如下: 在这里插入图片描述

五、配置文件解析ngx_conf_parse

配置文件解析的时候,分成三种类型解析: 一种是文件直接一行内容的解析如刚入nginx.conf或include一个文件的时候:parse_file; 一种是对形如xxx{}的配置块的解析:parse_block; 还有一种就是启动命令参数的解析:parse_param;

1、文件配置token解析ngx_conf_read_token 这个方法按行解析,以分号结束,一行读取,按换行符跳转下一行,以空格为参数分隔符。主要分几种情形: 以分号结束的一行: 每次解析一行结束开始下一行解析时,将cf->args清零,开始单行逐个字符遍历,遇到空格则分割一个关键词,将一行的多个关键词按序push到cf->args中,解析到分号时,结束当前行解析。并返回NGX_OK;如

daemon off;//解析改行后,cf->args有两个元素,分别为daemon,off text/html html htm shtml;//解析改行后,cf->args有四个元素,分别为text/html ,html, htm, shtml

以 ‘{’ 结束的一行: 表示进入块配置解析,解析出一个或多个关键词,并返回NGX_CONF_BLOCK_START;如

http { //解析出关键词http,并push到cf->args,返回NGX_CONF_BLOCK_START状态,表示开启块配置解析;

以 ‘}’ 结束的一行: 表示块配置解析结束,或者文件结束,返回NGX_CONF_BLOCK_DONE,NGX_CONF_FILE_DONE;

一行中存在#: 标记sharp_comment,跳过#后续字符处理

1、core域配置解析 core域配置解析通常是在nginx.conf中的第一级配置中如:daemon off; 在这里插入图片描述 在这里插入图片描述 在这里插入图片描述 其他同类型命令的解析流程基本也是如此;

2、event域配置解析 先来看看ngx_events_module的基本结构 在这里插入图片描述

当解析到events块时:

events { worker_connections 1024; }

先解析到events {,那么在hanlder方法中 在这里插入图片描述

在event域的模块的init_conf会对epoll进行初始化,后面再单独解读event与epoll,本文重点解读配置结构。那么处理到这里,配置的形态如图: 在这里插入图片描述

3、http域配置解析 先来看看ngx_http_module的基本结构 在这里插入图片描述 http的conf_ctx结构比较古怪,采用了分层的结构,分了三层,通过偏移量来找到每层的位置:

//64位系统中指针大小都是8字节,因此每个指针变量偏移量递增8 typedef struct { void **main_conf;//偏移量0 void **srv_conf; //偏移量8 void **loc_conf; //偏移量16 } ngx_http_conf_ctx_t;

可以看出,基本跟ngx_events_module的结构差不多 当解析到http块时:

http{ include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 8081; server_name localhost; location / { root html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }

先解析到http{,那么在hanlder方法中 在这里插入图片描述 在进入http{}的ngx_conf_parse前,会先对每个module进行预配置处理 module->preconfiguration(cf) 比如:ngx_http_core_preconfiguration会将ngx_http_core_variables中的所有配置配置到模块对应的ngx_http_core_main_conf_t配置的variables中。 创建配置后的结构大致如下:(只列出ngx_http_core_module与ngx_http_upstream_module) 在这里插入图片描述 下面来看下http块里的具体细节: include命令: 导入mime.types命令; 在这里插入图片描述 解析mime.types文件,首先解析types命令 ![在这里插入图片描述](https://img-blog.csdnimg.cn/3068aecb8cc84cdc9f2581cfc607e2b0.png 在这里插入图片描述 mime.types中其他行的处理大致一样。

解析server{}块 首先server命令时配置在ngx_http_core_commands中 在这里插入图片描述 server命令本身type还是属于ngx_http_main_conf的,进入ngx_http_core_server,开始server命令处理 在这里插入图片描述 此时http域的配置结构大致如下: 在这里插入图片描述

在server{}中会解析监听端口,servername,sendfile等配置,这些配置跟之前的解析差不多;server{}块中,还另外包含了location{}配置块,下面来解读:

location{}配置块解析: location命令配置在ngx_http_core_commands中 在这里插入图片描述 下面只解析配置结构相关的内容,location相关URL的处理逻辑可参考NGINX配置说明 server配置 location配置 在这里插入图片描述 location解析完之后的http域配置结构如图: 在这里插入图片描述

这图,相当恶心。到这里,整个配置的解析基本上就完成了。当然很多细节就没在这里关注了,debug的时候看下就行。 当然流程还没走完,回顾下,刚开始进入解析http块,执行完ngx_conf_parse后,还有一部分的后续处理,将留到下一篇继续解读。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3