Nginx请求执行阶段
Nginx在处理请求时,按照不同的阶段依次处理,常见的阶段如rewrite、access和content依次执行。Nginx中的指令一般只注册在某一个阶段,如echo注册在content阶段,set注册在rewrite阶段,因此set总是在echo之前执行,与书写顺序无关。特殊的,geo和map指令与处理阶段无关,它们是声明性的。
1,rewrite阶段
rewrite中的指令可以混合执行,如set、set_by_lua等,set_by_lua将计算结果赋予变量,如set_by_lua $c "return ngx.var.a + ngx.var.b"。ngx.var.VARIABLE 接口来读取 Nginx 变量 $VARIABLE,将a和b的和赋给c,特殊的当由于nginx中变量只能是字符串,而在lua中若a和b是数字的则会转换为数值类型再求和,转换为字符串赋给c。这些第三方模块注入到rewrite的指令序列中,而其他模块岁也在rewrite阶段,但和ngx_rewrite的指令分开执行,即使运行在同一个请求处理阶段,分属不同模块的配置指令也可能会分开独立运行。rewrite_by_lua指令也运行在rewrite阶段的末尾。
2,access阶段
执行在rewrite之后的access阶段的任务主要是执行访问控制的任务,如检查用户权限及IP合法性等。ngx_access的指令按顺序执行,直到遇到第一条满足的条件指令为止就不执行allow和deny。allow若先匹配则执行后续其他模块的指令,若deny先匹配则返回403。
ngx_lua模块的accessby_lua执行在access阶段,与rewrite_by_lua类似执行在access的末尾。可通过嵌入的lua代码执行较复杂的验证过程。执行效率较ngx_lua慢。
3,content阶段
执行在access之后的content阶段任务是生成响应内容并输出HTTP响应。如echo指令,echo_ecxec,proxy_pass,echo_location及content_by_lua都运行在此阶段。注意,与rewrite和access阶段不同,content阶段不同模块的配置指令不能一起混合使用。向 content 阶段注册配置指令本质上是在当前的 location 配置块中注册所谓的“内容处理程序”。而每一个 location 只能有一个“内容处理程序”,因此,当在 location 中同时使用多个模块的 content 阶段指令时,只有其中一个模块能成功注册“内容处理程序”。所以应当避免在同一个 location 中使用多个模块的 content 阶段指令。
content阶段包含三个静态资源服务模块,ngx_index,ngx_autoindex,ngx_static用于当在location未使用任何content阶段的指令时处理URL请求。ngx_index和ngx_autoindex只作用于已/结尾的URI,其他由ngx_static执行。
ngx_index使用index指令用于查找首页文件,配合root指令实现,当找到文件后触发内部跳转而不是直接返回该文件,若都不存在则返回403。ngx_autoindex用于开启目录索引autoindex on,当index指定的首页文件不存在时返回该目录索引。
ngx_static处理所有的静态资源的请求, /VAR/WWW/目录下有index.html文件,如:
location / {
root /var/www/;
}
当请求index.html时,该location匹配上,并最终由ngx_static处理,返回该index.html。若没有root指定根目录,则使用安装nginx时使用的--prefix目录.
4,其他阶段
Nginx的执行顺序为post-read、 server-rewrite、 findconfig、 rewrite、 post-rewrite、 preaccess、 access、 post-access、 try-files、 content 以及 log。
- post-read阶段。在nginx读取并解析完请求头之后立即执行,支持其他模块的注册,如ngx_realip 使Nginx 认为当前请求的来源地址是指定的某一个请求头的值。 set_real_ip_from指定来源的IP, real_ip_header更改的请求头。常用于当请求经过某一代理后其来源IP都为代理IP,一般会在代理之前把真实的IP放在HTP请求头中,再通过ngx_realip恢复。
- 写在server而不是location中的rewrite指令运行在该阶段。如set
- find-config不支持Nginx模块注册处理程序,由于Nginx核心完成请求与location的配对工作。
- post-rewrite阶段不支持Nginx模块注册处理程序,完成内部跳转。内部跳转本质上是把当前请求的处理阶段强行倒退到find-config节点使url与location重新匹配。
- preaccess阶段的ngx_limit_req用于控制请求的访问频度, ngx_limit_zone 用于控制访问的并发度。注册在location中的realip模块也在该阶段运行。
- post-access阶段。不支持模块注册,主要用于配合access实现标准 ngx_http_core 模块提供的配置指令 satisfy 的功能。satisfy用于access阶段注册的模块是and还是or验证。satisfy all/any。
- try-files阶段,后跟N各参数,Nginx按顺序检查前N-1个参数对应的文件是否存在,若存在则改写URI(不包含末尾的斜杠/),否则使用第N各参数内部跳转,而不检查对应的文件是否存在。最后一个参数也可为直接返回的状态码。
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐