nginx 源代码分析 (四)

2021-06-19  本文已影响0人  RonZheng2010

1. ngx_listening_t与ngx_connection_t

ngx_listening_t保存监听配置信息,如地址、端口等。Init_cycle.listening[]数组保存了所有的ngx_listening_t实例。

ngx_connection_t保存连接,如socket句柄等。Init_cycle.connections[]数组保存所有的ngx_connection_t实例,init_cycle.free_connections[]数组保存其中空闲的ngx_connection_t实例。init_cycle.connections[]的大小由init_cycle.connection_n指定,这个值缺省为512,也可以在配置文件中改变。

ngx_connection_t使用ngx_event_t保存读写事件的配置,如事件处理函数。

2. ngx_http_optimize_servers()

如前所述,http{}节点的ngx_http_main_conf_t.ports[]数组指向server{}的端口数组。nginx服务器绑定这些端口,监听连接请求。

ngx_http_optimize_servers() 根据从这些端口创建ngx_listening_t实例。

3. ngx_http_init_listening()

ngx_http_init_listening() 从ngx_http_core_main_conf_t.ports[]创建ngx_listenging_t实例,包括从ip地址到ngx_http_core_srv_conf的映射关系。

在ngx_http_init_listening()中,遍历ngx_http_core_main_conf_t.ports.addrs[],

4. ngx_open_listening_sockets()

ngx_open_listening_sockets()遍历init_cycle.listening[]数组,创建socket,绑定到指定的地址上,并开始监听。

5. ngx_configure_listening_sockets()

ngx_configure_listening_sockets()遍历init_cycle.listening[],对之前创建的socket继续进行选项配置。

6. ngx_event_process_init()

ngx_event_process_init()前面已经列出。

这里进一步详细说明的是,

7. ngx_process_events()

ngx_process_events()前面已经列出。

这里进一步说明的是,调用epoll_wait() 得到的事件epoll_event,与ngx_connetion_t实例相关联。这里遍历event_list[],对其中的epoll_event,

8. ngx_event_accept()

服务器监听端口有连接请求到达时,调用ngx_event_accept()。

9. 回顾ngx_http_add_listen()

在继续说明ngx_http_init_connection()之前,先回顾一下ngx_http_add_listen()。

创建server{}的配置数据结构时,调用ngx_http_core_listen()。得到server{}中的绑定地址后,调用ngx_http_add_listen() 加入ngx_http_core_main_conf.ports[]中。

这里涉及的数据结构如下。

10. 回顾ngx_http_init_listening()

在继续说明ngx_http_init_connection()之前,先回顾一下ngx_http_init_listening()。

ngx_http_init_listening() 从ngx_http_core_main_conf_t.ports[]创建ngx_listenging_t实例,包括从ip地址到ngx_http_core_srv_conf的映射关系。

这里涉及的数据结构如下。

所以,遍历ngx_listengint_t.servers[],可以根据地址找到对应的ngx_http_core_srv_conf_t实例。

11. ngx_http_init_connection()

ngx_http_init_connection()初始化新的ngx_connection_t实例。

hc->addr_conf = &addr[i].conf;
hc->conf_ctx = hc->addr_conf->default_server->ctx;

12. ngx_process_events()

再一次回到ngx_process_events()。这一次当数据连接socket有数据可读时,调用ngx_event_t::handler(),这里是ngx_http_wait_request_handler()。ngx_http_wait_request_handler()就开始处理http请求了。

13. ngx_http_wait_request_handler()

当http请求数据到达时,调用ngx_http_wait_request_handler()。它接收请求数据并处理。

14. ngx_http_create_request()

ngx_http_create_request() 创建ngx_http_request_t实例。它调用ngx_http_alloc_request()分配ngx_http_request_t实例。其中设置ngx_http_request_t.main_conf、ngx_http_request_t.srv_conf、ngx_http_request_t.loc_conf。这是后面的ngx_http_request_t的上下文。

15. ngx_http_request_t

ngx_http_request_t是http请求处理过程中使用的结构。解析请求字符串得到的信息保存在这里。

如下是一个请求字符串的例子。

这行调用ngx_http_parse_request_line()解析。

后续行为header行,每一行是一个header,包括名字和值。这里的header名字有User-Agent、Accept、Host和Connection。保存在ngx_http_request.headers_in.headers。Header行调用ngx_http_parse_header_line()解析。

16. ngx_http_headers_in

全局数组ngx_http_headers_in[]中,保存与header行对应的处理函数。如下面的Host、User-Agent等。

ngx_http_header_t  ngx_http_headers_in[] = {
    { ngx_string("Host"), offsetof(ngx_http_headers_in_t, host),
        ngx_http_process_host },
    { ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
        ngx_http_process_user_agent },
......
};

17. ngx_http_init_headers_in_hash()

在ngx_http_init_headers_in_hash()中,

ngx_array_t headers_in;

ngx_hash_init_t hash;

所以最后的结果就是,全局数组ngx_http_headers_in[]的元素保存在ngx_http_core_main_conf_t.headers_in_hash中,访问速度变快了。

18. ngx_http_process_request_line ()

ngx_http_process_request_line()负责处理请求字符串。

在一个循环中,执行如下步骤:

19. ngx_http_process_request_headers()

ngx_http_process_request_headers() 继续处理http请求。

20. ngx_http_process_request()

ngx_http_process_request() 处理http请求。它调用ngx_http_handler(),后者又调用ngx_http_core_run_phases()。

nginx将数据处理过程划分为几个阶段(phase),每个阶段可以挂接若干处理函数,ngx_http_core_run_phase() 按阶段调用这些函数。Nginx自身的nginx_module,用户自己的ngx_module,都可以挂接自己的处理函数。

上一篇 下一篇

猜你喜欢

热点阅读