Nginx处理HTTP请求的11个阶段

nginxHTTP请求处理流程分为11个阶段,绝大部分HTTP模块都会将自己的handler添加到某个阶段(将handler加入全局数组phases),nginx处理HTTP请求时会逐个调用每个阶段的handler,其中有4个阶段不能自定义handler11个阶段代码在/src/http/ngx_http_core_module.h中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
typedef enum {
//读取请求内容阶段
NGX_HTTP_POST_READ_PHASE = 0,

//server块配置rewrite指令,重写url
NGX_HTTP_SERVER_REWRITE_PHASE,

//查找匹配的location配置,不能自定义handler
NGX_HTTP_FIND_CONFIG_PHASE,

//location块配置rewrite指令,重写url
NGX_HTTP_REWRITE_PHASE,

//检查是否发生url重写,有,重新回到FIND_CONFIG阶段,不能自定义handler
NGX_HTTP_POST_REWRITE_PHASE,

//访问控制,比如限流模块会注册handler到此阶段
NGX_HTTP_PREACCESS_PHASE,

//访问权限控制,比如基于ip黑名单和用户密码权限控制
NGX_HTTP_ACCESS_PHASE,

//根据访问权限控制阶段做相应处理,不能自定义handler
NGX_HTTP_POST_ACCESS_PHASE,

//开始内容生成前阶段
NGX_HTTP_PRECONTENT_PHASE,

//内容产生阶段,返回响应给客户端
NGX_HTTP_CONTENT_PHASE,

//日志记录阶段,不能自定义handler
NGX_HTTP_LOG_PHASE
} ngx_http_phases;

通过gdb可以看到具体阶段对应的handler:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
gdb /usr/local/nginx16/sbin/nginx
b ngx_http_block
r
n
b 326
c
(gdb) p cmcf->phases
$1 = {{handlers = {elts = 0x7417f0, nelts = 0, size = 8, nalloc = 1, pool = 0x71d2e0}}, {handlers = {elts = 0x7417f8, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}, {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}, {handlers = {elts = 0x741800, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}, {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}, {handlers = { elts = 0x741e98, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}, {handlers = {elts = 0x741810, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}, {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}, {handlers = {elts = 0x741820, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}, {handlers = {elts = 0x741830, nelts = 3, size = 8, nalloc = 4, pool = 0x71d2e0}}, {handlers = { elts = 0x741850, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}}
(gdb) p cmcf->phases[0]
$2 = {handlers = {elts = 0x7417f0, nelts = 0, size = 8, nalloc = 1, pool = 0x71d2e0}}
(gdb) p *(ngx_http_handler_pt*)cmcf->phases[0].handlers.elts
$3 = (ngx_http_handler_pt) 0x0
(gdb) p cmcf->phases[1]
$4 = {handlers = {elts = 0x7417f8, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}
(gdb) p *(ngx_http_handler_pt*)cmcf->phases[1].handlers.elts
$5 = (ngx_http_handler_pt) 0x4aaeca <ngx_http_rewrite_handler>
(gdb) p cmcf->phases[2]
$6 = {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}
(gdb) p cmcf->phases[3]
$7 = {handlers = {elts = 0x741800, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}
(gdb) p *(ngx_http_handler_pt*)cmcf->phases[3].handlers.elts
$8 = (ngx_http_handler_pt) 0x4aaeca <ngx_http_rewrite_handler>
(gdb) p cmcf->phases[4]
$9 = {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}
(gdb) p cmcf->phases[5]
$10 = {handlers = {elts = 0x741e98, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}
(gdb) p *(ngx_http_handler_pt*)cmcf->phases[5].handlers.elts+0
$11 = (ngx_int_t (*)(ngx_http_request_t *)) 0x4a226e <ngx_http_limit_conn_handler>
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[5].handlers.elts+1)
$13 = (ngx_http_handler_pt) 0x4a343c <ngx_http_limit_req_handler>
(gdb) p cmcf->phases[6]
$14 = {handlers = {elts = 0x741810, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[6].handlers.elts+1)
$15 = (ngx_http_handler_pt) 0x4a1872 <ngx_http_access_handler>
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[6].handlers.elts)
$16 = (ngx_http_handler_pt) 0x4a0dcc <ngx_http_auth_basic_handler>
(gdb) p cmcf->phases[7]
$17 = {handlers = {elts = 0x0, nelts = 0, size = 0, nalloc = 0, pool = 0x0}}
(gdb) p cmcf->phases[8]
$18 = {handlers = {elts = 0x741820, nelts = 2, size = 8, nalloc = 2, pool = 0x71d2e0}}
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[8].handlers.elts)
$19 = (ngx_http_handler_pt) 0x49fbc0 <ngx_http_mirror_handler>
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[8].handlers.elts+1)
$20 = (ngx_http_handler_pt) 0x4a00b5 <ngx_http_try_files_handler>
(gdb) p cmcf->phases[9]
$21 = {handlers = {elts = 0x741830, nelts = 3, size = 8, nalloc = 4, pool = 0x71d2e0}}
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[9].handlers.elts)
$22 = (ngx_http_handler_pt) 0x49bcff <ngx_http_static_handler>
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[9].handlers.elts+1)
$23 = (ngx_http_handler_pt) 0x49c685 <ngx_http_autoindex_handler>
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[9].handlers.elts+2)
$24 = (ngx_http_handler_pt) 0x49ec96 <ngx_http_index_handler>
(gdb) p cmcf->phases[10]
$25 = {handlers = {elts = 0x741850, nelts = 1, size = 8, nalloc = 1, pool = 0x71d2e0}}
(gdb) p *((ngx_http_handler_pt*)cmcf->phases[10].handlers.elts)
$26 = (ngx_http_handler_pt) 0x466ea5 <ngx_http_log_handler>
(gdb) p cmcf->phases[11]
$27 = {handlers = {elts = 0x733288, nelts = 0, size = 0, nalloc = 0, pool = 0x721340}}

11个阶段注册handler如下:
nginx 11个阶段图解