Nginx的指令的执行顺序:

一、post-read

  ngx_realip模块的set_real_ip_from和real_ip_header指令(在server里面配置的)

二、server-rewrite

  ngx_rewrite模块的set指令和rewrite指令(前提在server里面配置时)

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
server {
  listen 8080;
  rewrite ^/foo /bar;
  location /foo {
    echo foo;
  }
  location /bar {
    echo bar;
  }
}

 

三、find-config(不接受模块注册处理程序)

  进行location的配对

四、rewrite

  ngx_rewrite模块的set指令和rewrite指令(前提在location里面配置时)

  ngx_set_misc模块的set_unescape_uri指令

  ngx_lua模块的set_by_lua指令

  rewrite tail:

  ngx_headers_more模块的more_set_input_headers指令

  ngx_lua模块的rewrite_by_lua指令

五、post-rewrite(不接受模块注册处理程序)

  实现在rewrite阶段的内部跳转

  “内部跳转”本质上其实就是把当前的请求处理阶段强行倒退到 find-config 阶段,以便重新进行请求URI 与 location 配置块的配对

  rewrite阶段的rewrite指令

location /foo {
  rewrite ^ /bar;
  rewrite ^ /baz;
  echo foo;
}

  两个rewrite语句都会执行,但只有最后一个才会起作用。因为rewrite指令在rewrite阶段执行,但是真正的内部跳转确是在post-rewrite阶段

六、preaccess

  ngx_realip模块的set_real_ip_from和real_ip_header指令(在location里面配置的)

七、access

  ngx_access模块的allow指令和deny指令(多个指令会按顺序进行执行)

  如果首先匹配的指令是 allow,则会继续执行后续其他模块的指令或者跳到后续的处理阶段;而如果首先满足的是 deny 则会立即中止当前整个请求的处理,并立即返回 403 错误页。

  access tail:

  ngx_lua模块的access_by_lua指令

  tips:指令中return表示该指令就是,继续执行后续的指令。

  tips:ngx_lua模块的ngx.exit(403)函数,直接结束整个请求处理过程,返回403页面。

八、post-access(不接受模块注册处理程序)

  ngx_http_core模块的satisfy指令

  对于多个 Nginx 模块注册在 access 阶段的处理程序, satisfy 配置指令可以用于控制它们彼此之间的协作方式。比如模块 A 和 B 都在 access 阶段注册了与访问控制相关的处理程序,那就有两种协作方式,一是模块 A 和模块 B 都得通过验证才算通过,二是模块 A 和模块 B 只要其中任一个通过验证就算通过。第一种协作方式称为 all 方式(或者说“与关系”),第二种方式则被称为 any 方式(或者说“或关系”)。默认情况下,Nginx 使用的是 all 方式。

location /test {
  satisfy all;
  deny all;
  access_by_lua 'ngx.exit(ngx.OK)';
  echo something important;
}

  比如上面这个就是在access阶段的ngx_access模块的程序和ngx_lua模块的关系是与的关系,两个都通过才可以。由于deny all,所以就都返回403了。

  deny all和access_by_lua 'ngx.exit(ngx.HTTP_FORBIDDEN)';效果一样。

九、try-files(不接受模块注册处理程序)

  配置指令try_files

  try_files 指令接受两个以上任意数量的参数,每个参数都指定了一个 URI. 这里假设配置了 N 个参数,则 Nginx 会在 try-files 阶段,依次把前 N-1 个参数映射为文件系统上的对象(文件或者目录),然后检查这些对象是否存在。一旦 Nginx 发现某个文件系统对象存在,就会在 try-files 阶段把当前请求的 URI 改写为该对象所对应的参数 URI(但不会包含末尾的斜杠字符,也不会发生 “内部跳转”),然后执行下一个阶段。如果前 N-1 个参数所对应的文件系统对象都不存在,try-files 阶段就会立即发起“内部跳转”到最后一个参数(即第 N 个参数)所指定的 URI.

root /var/www/;
location /test {
  try_files /foo /bar/ /baz;
  echo "uri: $uri";
}
location /foo {
  echo foo;
}
location /bar/ {
  echo bar;
}

  假设现在 /var/www/ 路径下是空的,则第一个参数 /foo 映射成的文件 /var/www/foo 是不存在的;同样,对于第二个参数/bar/ 所映射成的目录 /var/www/bar/ 也是不存在的。于是此时 Nginx 会在 try-files 阶段发起到最后一个参数所指定的 URI(即 /baz)的“内部

跳转”。当/bar/目录存在时,URI会被改写成/bar,末尾的'/'会被去掉。

  当然,除了无条件地发起“内部跳转”之外, try_files 指令还支持直接返回指定状态码的HTTP 错误页,例如:try_files /foo /bar/ =404;

十、content阶段:

  这个阶段的这么多的指令只能有一种胜出。每一个location只能有一个内容处理程序。

  执行的顺序是:如果1里面有就从里面选择一个执行,如果1里面没有就让2执行,如果2没有或者处理不了就让3执行,如果3没有或者处理不了就让4执行。

1、ngx_echo模块的echo指令、echo_exec指令、echo_location指令

  ngx_proxy模块的proxy_pass指令

  ngx_lua模块的content_by_lua指令

  用一种指令有的可以写几次,比如echo。

location /test {
  echo hello;
  echo world;
}

  ngx_lua模块的ngx.say函数和ngx_echo模块的echo函数是一样的

location /test {
  content_by_lua 'ngx.say("hello") ngx.say("world")';
}

tips:当“文档根目录”是 /var/www/ 的时候,请求 URI /foo/bar 会被映射为文件 /var/www/foo/bar,而请求 URI /foo/baz/ 则会被映射为目录/var/www/foo/baz/. 注意这里是如何通过 URI 末尾的斜杠字符是否存在来区分“目录”和“文件”的。(这个是对于2、3、4来说的)

2、ngx_index模块的index指令:

  处理以'/'结尾的请求

location / {
  root /var/www/;
  index index.htm index.html;
}

  当用户请求'/'地址时,Nginx会自动在/var/www/index.htm目录下寻找这个文件,如果找到,则直接发起内部跳转到新的'/index.html'这个新的地址,如果不存在,则继续找/var/www/index.html这个文件,如果找得到,则直接发起内部跳转到'/index.html'这个地址,如果不存在,就交给后续的模块进行处理,如果都处理不了,就报403的错误。

3、ngx_autoindex模块的autoindex指令:

  处理以'/'结尾的请求

  自动生成目录索引页

location / {
root /var/www/;
index index.html;
autoindex on;
}

  当请求到来时,当/var/www/index.html的页面不存在时,会显示/var/www/下的文件目录列表;当index.html的存在时,会优先执行ngx_index模块的index指令,直接发生内部跳转。

4、ngx_static模块的静态资源指令:

  处理不以'/'结尾的网页

  专门用来处理和输出静态资源内容的

location / {
}

  因为没有配置 root 指令,所以在访问这个接口时,Nginx 会自动计算出一个缺省的“文档根目录”。该缺省值是取所谓的“配置前缀 prefix路径下的 html/ 子目录。举一个例子,假设配置前缀是 /foo/bar/,则缺省的“文档根目录”便是 /foo/bar/html/。

  当静态资源找不到时会出现404错误。404是指静态资源找不到,而并非location找不到。

十一、log

参考知识点:

1、内部跳转:(浏览器地址不发生变化)

  ngx_index模块的index指令

  echo模块的echo_exec指令

  ngx_rewrite模块的rewrite指令

  try_files的最后一跳

2、HTTP的头部参数的获取

  $http_XXX 内建变量在读取时会返回当前请求中名为 XXX 的请求头

  需要注意的是, $http_XXX 变量在匹配请求头时会自动对请求头的名字进行归一化,即将名字的大写字母转换为小写字母,同时把间隔符(-)替换为下划线(_)

3、输出过滤器

  ngx_echo模块的echo_before_body和echo_after_body

  Nginx 在输出响应体数据时都会调用“输出过滤器”,不属于某个阶段,只要有输出响应,就会调用输出过滤器。

4、外部跳转

  302 和 301 响应的“外部跳转”,浏览器地址发生变化。

  

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄