本篇文章给大家带来的内容是关于nginx HTTP处理流程的浅析,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
1.初始化服务器
server指令用于配置virtual server,我们通常会在一台机器配置多个virtual server,监听不同端口号,映射到不同文件目录;nginx解析用户配置,在所有端口创建socket并启动监听。
nginx解析配置文件是由各个模块分担处理的,每个模块注册并处理自己关心的配置,通过模块结构体ngx_module_t的字段ngx_command_t *commands实现;
例如ngx_http_module是一个核心模块,其commands字段定义如下:
struct ngx_command_s { ngx_str_t name; ngx_uint_t type; char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);}; static ngx_command_t ngx_http_commands[] = { { ngx_string("http"), NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_http_block, },};
-
name指令名称,解析配置文件时按照名称能匹配查找;
-
type指令类型,NGX_CONF_本文来源gao@!dai!ma.com搞$$代^@码!网!搞gaodaima代码NOARGS该配置无参数,NGX_CONF_BLOCK该配置是一个配置块,NGX_MAIN_CONF表示配置可以出现在哪些位(NGX_MAIN_CONF、NGX_HTTP_SRV_CONF、NGX_HTTP_LOC_CONF);
-
set指令处理函数指针;
可以看到解析http指令的处理函数为ngx_http_block,实现如下:
static char * ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ //解析main配置 //解析server配置 //解析location配置 //初始化HTTP处理流程所需的handler //初始化listening if (ngx_http_optimize_servers(cf, cmcf, cmcf->ports) != NGX_OK) { return NGX_CONF_ERROR; }}
ngx_http_optimize_servers方法循环所有配置端口,创建ngx_listening_t对象,并将其添加到conf->cycle->listening(后续操作会遍历此数组,创建socket并监听)。方法主要操作如下图:
注意到这里设置了ngx_listening_t的handler为ngx_http_init_connection,当接收到socket连接请求时,会调用此handler处理。
那么什么时候启动监听呢?全局搜索关键字cycle->listening可以找到。main方法会调用ngx_init_cycle,其完成了服务器初始化的大部分工作,其中就包括启动监听(ngx_open_listening_sockets)。
假设nginx使用epoll处理所有socket事件,什么时候将监听事件添加到epoll呢?全局搜索关键字cycle->listening可以找到。ngx_event_core_module模块是事件处理核心模块,初始化此模块时会执行ngx_event_process_init函数,其中将监听事件添加到epoll。
static ngx_int_t ngx_event_process_init(ngx_cycle_t *cycle){ ls = cycle->listening.elts; for (i = 0; i < cycle->listening.nelts; i++) { //设置读事件处理handler rev->handler = ngx_event_accept; ngx_add_event(rev, NGX_READ_EVENT, 0); }}
注意到接收到客户端socket连接请求事件的处理函数是ngx_event_accept。
2.HTTP请求解析
2.1 基础结构体
结构体ngx_connection_t存储socket连接相关信息;nginx预先创建若干个ngx_connection_t对象,存储在全局变量ngx_cycle->free_connections,称之为连接池;当新生成socket时,会尝试从连接池中获取空闲connection连接,如果获取失败,则会直接关闭此socket。
指令worker_connections用于配置连接池最大连接数目,配置在events指令块中,由ngx_event_core_module解析。
vents { use epoll; worker_connections 60000;}