nginx_0.1.0分析

框架代码分析

核心模块

启动过程(main)

1、全局ngx_cycle_t对象

1、ngx_init_cycle

2、cycle->listening对象数组(ngx_listening_t对象数组)

2、cycle->conf_ctx指针数组

2、各个CORE模块create_conf创建配置对象,赋值给conf_ctx指针数组

2、ngx_conf_parse解析所有配置文件到conf_ctx指针数组

2、各个CORE模块init_conf配置缺省默认值

2、ngx_open_listening_sockets监听端口(数据来源:listening对象数组)

2、所有模块init_module过程

1、ngx_single_process_cycle

2、所有模块init_process过程

2、死循环处理事件:ngx_process_events

P.S. http{}解析完,会调用ngx_core_listen_parse将端口信息拷贝到listening对象数组,设置处理函数为ngx_http_init_connection(tcp建链完成后的处理函数入口)

配置解析功能(ngx_conf_parse)

(1)如核心模块中user、group配置(core模块)

conf_ctx指针数组中指针直接指向配置对象

(2)如events{}中multi_accept配置(event_core模块)、events配置(epoll模块)

conf_ctx指针数组中指针指向指针A,指针A指向配置对象指针数组(数组个数为event模块数,指针数组中各指针指向各event模块特有的配置对象)

(3)如https{}中配置(event_core模块)、events配置(epoll模块)

conf_ctx指针数组中指针指向根ngx_http_conf_ctx_t对象,每个{}信息存储在独立的ngx_http_conf_ctx_t对象中,通过链表进行级联)

1、ngx_events_block

1、指针对象、指针数组

1、所有event模块的create_conf过程

1、ngx_conf_parse嵌套解析events{}中的配置信息

1、所有event模块的init_conf过程

2、ngx_http_block

1、根ngx_http_conf_ctx_t对象、三个成员指向三个指针数组

1、所有http模块的pre_conf过程

1、所有http模块的create_main_conf过程

1、所有http模块的create_srv_conf过程

1、所有http模块的create_loc_conf过程

1、ngx_conf_parse嵌套解析https{}中的配置信息

1、各类merge过程定义配置信息作用范围

1、所有http模块的init_main_conf过程

1、ngx_core_prepare_phasesconn处理流水线过程(可三方模块嵌入)

1、ngx_core_listen_parse将端口信息拷贝listening对象数组,设置处理函数为ngx_http_init_connection(tcp建链完成后的处理函数入口)

3、ngx_server_block

1、新ngx_http_conf_ctx_t对象、新2个成员指向2个指针数组(main_conf共用)

1、所有http模块的create_srv_conf过程

1、所有http模块的create_loc_conf过程

1、ngx_http_core_srv_conf_t对象指针插入根ngx_http_core_main_conf_t对象的servers数组

1、ngx_conf_parse嵌套解析servers{}中的配置信息

1、location排序

4、ngx_location_block

1、新ngx_http_conf_ctx_t对象

1、新loc_conf对象指向1个指针数组(main_conf、srv_conf共用)

1、所有http模块的create_loc_conf过程

1a、ngx_http_core_loc_conf_t指针插入上层ngx_http_core_srv_conf_t对象的location数组

1b、ngx_http_core_loc_conf_t指针插入上层ngx_http_core_loc_conf_t对象的location数组

1、ngx_conf_parse嵌套解析location{}中的配置信息

举例NGX_CORE_MODULE模块NGX_MAIN_CONF配置的解析

1、此时文件未打开,故ngx_open_file打开文件

1、循环用ngx_conf_read_token读取每一行

1、扫描所有模块,对指定模块指定配置进行匹配,并校验配置个数的正确性

1、NGX_DIRECT_CONF配置是直接使用ngx_core_conf_t对象

2、cmd->set是直接使用ngx_core_conf_t对象

3、如ngx_conf_set_flag_slot

1、NGX_MAIN_CONF配置是指针数组,指向特殊对象内存。如event核心模块指向event模块个数组成的指针数组,每个成员指向对应模块的对象(event_core_t模块指向event_conf_t对象,epoll_module模块指向epoll_conf_t对象)

2、cmd->set是指向指针数组(各指针使用各自模块定义的对象)。

3、如ngx_events_block、ngx_http_block

1、其他配置说明该ngx_conf_parse例程处于嵌套中

2、cmd->set是指向指针数组中,当前模块对应的定义对象

3、如ngx_event_connections(event_core根模块中connections配置项)

举例NGX_HTTP_MODULE模块NGX_HTTP_MAIN_CONF配置的解析

1、循环用ngx_conf_read_token读取每一行

1、扫描所有模块,对指定模块指定配置进行匹配,并校验配置个数的正确性

1、其他配置说明该ngx_conf_parse例程处于嵌套中(此时cf->ctx指向起始的ngx_http_conf_ctx_t对象)

2、cmd->set是指向main_conf中,当前模块对应的定义对象

3、如ngx_conf_set_size_slot(http_core根模块中connection_pool_size配置项)

3、如ngx_server_block(http_core根模块中server配置项)

1、ngx_server_block

参数cf指向http_core_main_conf_t对象,cmd指向下面截图内容:

server{}

2、继续创建同样的对象组,调用ngx_conf_parse进行嵌套配置解析NGX_HTTP_SRV_CONF配置(cf->ctx变成新的ngx_http_conf_ctx_t对象)。

举例NGX_HTTP_MODULE模块NGX_HTTP_SRV_CONF配置的解析

1、循环用ngx_conf_read_token读取每一行

1、扫描所有模块,对指定模块指定配置进行匹配,并校验配置个数的正确性

1、其他配置说明该ngx_conf_parse例程处于嵌套中

2、cmd->set是指向srv_conf中,当前模块对应的定义对象

3、如ngx_conf_set_size_slot(http_core根模块中listen配置项)

3、如ngx_location_block(http_core根模块中location配置项)

1、ngx_loc_block

参数cf指向http_core_srv_conf_t对象,cmd指向下面截图内容:

location{}

2、继续创建同样的对象组,调用ngx_conf_parse进行嵌套配置解析NGX_HTTP_LOC_CONF配置(cf->ctx变成新的ngx_http_conf_ctx_t对象)。

举例NGX_HTTP_MODULE模块NGX_HTTP_LOC_CONF配置的解析

1、循环用ngx_conf_read_token读取每一行

1、扫描所有模块,对指定模块指定配置进行匹配,并校验配置个数的正确性

1、其他配置说明该ngx_conf_parse例程处于嵌套中

2、cmd->set是指向srv_conf中,当前模块对应的定义对象

3、如ngx_set_root(http_core根模块中alias配置项)

3、如ngx_location_block(http_core根模块中location配置项)

location是可以无限嵌套的。

总结

文字分析的逻辑往往让人一头雾水,图文并茂才不坑人坑己,配置项影响范围是由各自模块去决定的,本文档讨论的均不涉及merge(各种merge函数起始就是把链表中的数据merge到外圈里的对象而已,很简单)。总结:

配置:

配置信息

对象:

配置信息组织形式

代码:

代码信息

从代码可知,http_test配置项可配置在任意{}中,srv_test配置项只能在server{}或location{}中,listen只能在server{}中,loc_test只能在location{}中,对应的对象组成就是上图所示。

上述总结例子中体现的配置细节不多。其实,http{}中也可以把信息存在loc_conf对象中;http_test存在server{}、location{}中的位置等等。至于作用范围则是根据你的三方模块中如何处理merge钩子了。

配置说明总结

http是最复杂的一个,总结了http模块,其他的就简单了。

1、NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF

NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF分别说明该配置项可以出现再http{}、server{}、location{}中。

2、NGX_CONF_NOARGS、NGX_CONF_TAKE1、NGX_CONF_1MORE

说明参数个数,配置校验使用。

3、NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET、NGX_HTTP_LOC_CONF_OFFSET

NGX_HTTP_MAIN_CONF_OFFSET、NGX_HTTP_SRV_CONF_OFFSET和NGX_HTTP_LOC_CONF_OFFSET指明该配置信息存储的数组,不同数组的效果如下(假定配置了NGX_HTTP_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF参数):

1NGX_HTTP_MAIN_CONF_OFFSET

整个http{}中仅能出现一次,否则会冲突,提示“is duplicate”。

2NGX_HTTP_SRV_CONF_OFFSET

http{}中仅能直接出现一次,嵌套的每个server{}(整个server{})也仅能出现一次,否则会冲突,提示“is duplicate”。

3NGX_HTTP_LOC_CONF_OFFSET

http{}中仅能直接出现一次,嵌套的每个server{}也仅能直接出现一次,任意server中嵌套的每个location{}也仅能直接出现一次,任意location中嵌套的每个location{}也仅能直接出现一次。

event模块

1、event_core模块

init_module过程: ngx_event_module_init

1、无

init_process过程:ngx_event_process_ini_t

1、获取ngx_event_conf_t对象

1、所有event模块的actions.init过程

1、connections数组、read_events数组、write_events数组

1、端口句柄收信号的处理为ngx_event_accept

1、ngx_add_event添加读事件(端口句柄)

端口读处理函数: ngx_event_accept

1、accept生成业务句柄

1、设置句柄属性

1、ngx_add_conn(如epoll模块的add_conn函数:)

1、执行listening的handle入口(ngx_http_init_connection)

2、epoll模块

init_module过程:

init_process过程

actions.init过程:ngx_epoll_init

1、epoll_create创建epoll对象

1、epoll_event数组

1、设置ngx_event_actions事件处理接口为epoll模块定义的ngx_epoll_module_ctx对象成员

actions.add_conn过程(ngx_add_conn):ngx_epoll_add_connection

端口收到信息,ngx_event_accept就会创建业务句柄,执行句柄的add_conn操作。

1、epoll_ctl添加读写事件到epoll对象

actions.add过程(ngx_add_event):ngx_epoll_add_event

添加事件(读、写等等)

1、epoll_ctl添加/修改读/写事件到epoll对象

http模块

http_core模块

init_module过程:

init_process过程

ngx_http_init_connection过程

http_core模块针对业务句柄的统一入口,设置事件的处理函数。

1、设置写事件入口为:ngx_http_empty_handler;

1、设置读事件入口为:ngx_http_init_request(rev);并进入

2、创建ngx_http_connection_t对象

2、创建ngx_http_request_t对象

2、创建读缓冲区

2、设置读事件入口为:ngx_http_process_request_line,并进入

3、ngx_http_read_request_header调用connection->recv进行socket读。

3、ngx_http_parse_request_line解析请求行

3、创建headers_in.headers队列、headers_in.cookies数组

3、设置读事件入口为:ngx_http_process_request_headers,并进入

4、ngx_http_read_request_header调用connection->recv进行socket读。

4、读完后调用ngx_http_parse_header_line解析请求头部

4a、头信息正确,记录到headers_in.headers队列

4c、头信息错误,关闭链接

4b、头信息解析完毕,设置读事件入口为:ngx_http_block_read(终止读body,先执行流水线)。

4b、ngx_http_handler进入http流水线处理。

ngx_http_handler过程

1、设置写事件入口为:ngx_http_phase_event_handler

1、执行ngx_http_run_phases

2、(ngx_http_phases定义了阶段。每个阶段有模块入口函数组成的数组。)

2、依次执行每个阶段。调用各个阶段里的函数操作

2、ngx_http_finalize_request请求的收尾工作


阶段一:NGX_HTTP_REWRITE_PHASE

ngx_http_rewrite_module模块负责阶段一的工作。

***http_rewrite模块初始化(init_module):ngx_http_rewrite_init***

设置阶段一NGX_HTTP_REWRITE_PHASE的处理入口为函数ngx_http_rewrite_handler

***阶段一处理:ngx_http_rewrite_handler***

获取所有rewrite配置项信息,依次做正则匹配,替换ngx_http_request_t对象的uri。

一般回复NGX_DECLINED状态进入下一个阶段一处理(没有),最后进入阶段二。


阶段二:NGX_HTTP_FIND_CONFIG_PHASE

ngx_http_block中已经设置NGX_HTTP_FIND_CONFIG_PHASE的处理入口函数为ngx_http_find_location_config

***阶段二处理:ngx_http_find_location_config***

使用ngx_http_request_t对象的uri成员去匹配配置文件中的location{}信息,将匹配到的location信息记录到loc_conf成员。(配置代理模式(ngx_http_proxy_module模块的proxy_pass配置项)时,设置content_handler为ngx_http_proxy_handler;配置重定向模式(ngx_http_rewrite_module模块redirect配置项)时,设置content_handler为ngx_http_redirect_handler,要细研究下)


阶段三:NGX_HTTP_ACCESS_PHASE

ngx_http_access_module模块负责阶段三的工作。

***ngx_http_access_module模块初始化(init_module):ngx_http_access_init***

***阶段三处理:ngx_http_access_handler***

匹配ngx_http_access_commands模块的allow配置项,则通过权限验证;

匹配ngx_http_access_commands模块的deny配置项,则不通过权限验证;


阶段四:NGX_HTTP_CONTENT_PHASE

ngx_http_index_module模块和ngx_http_static_module模块负责阶段四的工作。

(排在前面的后执行,排在后面的先执行)

***模块初始化(init_module):ngx_http_index_initngx_http_static_init***

***阶段四处理1ngx_http_index_handler***

1、创建ngx_http_index_ctx_t对象(r->ctx[ngx_http_index_module])

1、

***阶段四处理2ngx_http_static_handler***

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容