Nginx 配置指令的执行顺序(七)

来看一个 ngx_static 模块服务磁盘文件的例子。我们使用下面这个配置片段:

    location / {        root /var/www/;    }

同时在本机的 /var/www/ 目录下创建两个文件,一个文件叫做 index.html,内容是一行文本 this is my home;另一个文件叫做 hello.html,内容是一行文本 hello world. 同时注意这两个文件的权限设置,确保它们都对运行 Nginx worker 进程的系统帐户可读。

现在来通过 HTTP 协议请求一下这两个文件所对应的 URI:

    $ curl ‘http://localhost:8080/index.html‘    this is my home     $ curl ‘http://localhost:8080/hello.html‘    hello world

我们看到,先前创建的那两个磁盘文件的内容被分别输出了。

不妨来分析一下这里发生的事情:location / 中没有使用运行在 content 阶段的模块指令,于是也就没有模块注册这个 location 的“内容处理程序”,处理权便自动落到了在 content 阶段“垫底”的那 3 个静态资源服务模块。首先运行的 ngx_index 和 ngx_autoindex 模块先后看到当前请求的 URI,/index.html 和/hello.html,并不以 / 结尾,于是直接弃权,将处理权转给了最后运行的 ngx_static 模块。ngx_static 模块根据 root 指令指定的“文档根目录”(document root),分别将请求 URI /index.html 和 /hello.html映射为文件系统路径 /var/www/index.html 和 /var/www/hello.html,在确认这两个文件存在后,将它们的内容分别作为响应体输出,并自动设置 Content-TypeContent-Length 以及 Last-Modified 等响应头。

为了确认 ngx_static 模块确实运行了,可以启用 (一) 中介绍过的 Nginx “调试日志”,然后再次请求 /index.html 这个接口。此时,在 Nginx 错误日志文件中可以看到类似下面这一行的调试信息:

    [debug] 3033#0: *1 http static fd: 8

这一行信息便是 ngx_static 模块生成的,其含义是“正在输出的静态文件的描述符是数字 8”。当然,具体的文件描述符编号会经常发生变化,这里只是我机器的一次典型输出。值得一提的是,能生成这一行调试信息的还有标准模块 ngx_gzip_static ,但它默认是不启用的,后面会专门介绍到这个模块。

注意上面这个例子中使用的 root 配置指令只起到了声明“文档根目录”的作用,并不是它开启了ngx_static 模块。ngx_static 模块总是处于开启状态,但是否轮得到它运行就要看 content 阶段先于它运行的那些模块是否“弃权”了。为了进一步确认这一点,来看下面这个空白 location 的定义:

    location / {    }

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

那么“配置前缀”是由什么来决定的呢?默认情况下,就是 Nginx 安装时的根目录(或者说 Nginx 构造时传递给 ./configure 脚本的 --prefix 选项的路径值)。如果 Nginx 安装到了 /usr/local/nginx/ 下,则“配置前缀”便是 /usr/local/nginx/,同时默认的“文档根目录”便是 /usr/local/nginx/html/. 不过,我们也可以在启动 Nginx 的时候,通过 --prefix 命令行选项临时指定自己的“配置前缀”路径。假设我们启动 Nginx 时使用的命令是

    nginx -p /home/agentzh/test/

则对于该服务器实例,其“配置前缀”便是 /home/agentzh/test/,而默认的“文档根目录”便是/home/agentzh/test/html/. “配置前缀”不仅会决定默认的“文档根目录”,还决定着 Nginx 配置文件中许多相对路径值如何解释为绝对路径,后面我们还会看到许多需要引用到“配置前缀”的例子。

获取当前“文档根目录”的路径有一个非常简便的方法,那就是请求一个肯定不存在的文件所对应的资源名,例如:

    $ curl ‘http://localhost:8080/blah-blah.txt‘    <html>    <head><title>404 Not Found</title></head>    <body bgcolor="white">    <center><h1>404 Not Found</h1></center>    <hr><center>nginx</center>    </body>    </html>

我们会很自然地得到 404 错误页。此时再看 Nginx 错误日志文件,应该会看到类似下面这一行错误消息:

    [error] 9364#0: *1 open() "/home/agentzh/test/html/blah-blah.txt" failed (2: No such file or directory)

这条错误消息是 ngx_static 模块打印出来的,因为它并不能在文件系统的对应路径上找到名为 blah-blah.txt的文件。因为这条错误信息中包含有 ngx_static 试图打开的文件的绝对路径,所以从这个路径不难看出,当前的“文档根目录”是 /home/agentzh/test/html/.

很多初学者会想当然地把 404 错误理解为某个 location 不存在,其实上面这个例子表明,即使 location存在并成功匹配,也是可能返回 404 错误页的。因为决定着 404 错误页的是抽象的“资源”是否存在,而非某个具体的 location 是否存在。

初学者常犯的一个错误是忘记配置 content 阶段的模块指令,而他们自己其实并不期望使用 content 阶段缺省运行的静态资源服务,例如:

    location /auth {        access_by_lua ‘            -- a lot of Lua code omitted here...        ‘;    }

显然,这个 /auth 接口只定义了 access 阶段的配置指令,即 access_by_lua,并未定义任何 content 阶段的配置指令。于是当我们请求 /auth 接口时,在 access 阶段的 Lua 代码会如期执行,然后 content 阶段的那些静态文件服务会紧接着自动发生作用,直至 ngx_static 模块去文件系统上找名为 auth 的文件。而经常地,404 错误页会抛出,除非运气太好,在对应路径上确实存在一个叫做 auth 的文件。所以,一条经验是,当遇到意外的 404 错误并且又不涉及静态文件服务时,应当首先检查是否在对应的 location 配置块中恰当地配置了 content 阶段的模块指令,例如 content_by_lua、 echo 以及 proxy_pass 之类。当然,Nginx 的error.log 文件一般总是会提供各种意外问题的答案,例如对于上面这个例子,我的 error.log 中有下面这条错误信息:

    [error] 9364#0: *1 open() "/home/agentzh/test/html/auth" failed (2: No such file or directory)
时间: 2024-08-25 11:01:05

Nginx 配置指令的执行顺序(七)的相关文章

Nginx 配置指令的执行顺序(八)

前面我们详细讨论了 rewrite.access 和 content 这三个最为常见的 Nginx 请求处理阶段,在此过程中,也顺便介绍了运行在这三个阶段的众多 Nginx 模块及其配置指令.同时可以看到,请求处理阶段的划分直接影响到了配置指令的执行顺序,熟悉这些阶段对于正确配置不同的 Nginx 模块并实现它们彼此之间的协同工作是非常必要的.所以接下来我们接着讨论余下的那些阶段. 前面在 (一) 中提到,Nginx 处理请求的过程一共划分为 11 个阶段,按照执行顺序依次是 post-read

Nginx 配置指令的执行顺序(一)

大多数 Nginx 新手都会频繁遇到这样一个困惑,那就是当同一个 location 配置块使用了多个 Nginx 模块的配置指令时,这些指令的执行顺序很可能会跟它们的书写顺序大相径庭.于是许多人选择了“试错法”,然后他们的配置文件就时常被改得一片狼藉.这个系列的教程就旨在帮助读者逐步地理解这些配置指令背后的执行时间和先后顺序的奥秘. 现在就来看这样一个令人困惑的例子:     ? location /test {    ?     set $a 32;    ?     echo $a;    

Nginx 配置指令的执行顺序(二)

我们前面已经知道,当 set 指令用在 location 配置块中时,都是在当前请求的 rewrite 阶段运行的.事实上,在此上下文中,ngx_rewrite 模块中的几乎全部指令,都运行在 rewrite 阶段,包括 Nginx 变量漫谈(二) 中介绍过的 rewrite 指令.不过,值得一提的是,当这些指令使用在 server 配置块中时,则会运行在一个我们尚未提及的更早的处理阶段,server-rewrite 阶段. Nginx 变量漫谈(二) 中介绍过的 ngx_set_misc 模块

Nginx 配置指令的执行顺序(十一)

紧跟在 post-access 阶段之后的是 try-files 阶段.这个阶段专门用于实现标准配置指令 try_files 的功能,并不支持 Nginx 模块注册处理程序.由于 try_files 指令在许多 FastCGI 应用的配置中都有用到,所以我们不妨在这里简单介绍一下. try_files 指令接受两个以上任意数量的参数,每个参数都指定了一个 URI. 这里假设配置了 N 个参数,则 Nginx 会在 try-files 阶段,依次把前 N-1 个参数映射为文件系统上的对象(文件或者

NGINX openrestry(指令的执行顺序)

Nginx的指令的执行顺序: 一.post-read 二.server-rewrite ngx_rewrite模块的set指令和rewrite指令(前提在server里面配置时) 三.find-config 四.rewrite ngx_rewrite模块的set指令和rewrite指令(前提在location里面配置时) ngx_set_misc模块的set_unescape_uri指令 ngx_lua模块的set_by_lua指令 rewrite tail: ngx_headers_more模

Nginx 配置指令location 匹配符优先级和安全问题【转】

Nginx配置指令location匹配符优先级和安全问题 使用nginx 很久了,它的性能高,稳定性表现也很好,得到了很多人的认可.特别是它的配置,有点像写程序一样,每行命令结尾一个";"号,语句块用"{}"括起来.配制好,直接nginx -t 检查配制情况,配制成功,直接运行:service nginx reload.服务器没有任何宕机情况下,实现平稳修改配置.最近一直在做location 配置,遇到优先级别问题(如果配置不当可能存在安全隐患哦),以下是个人学习一

Nginx配置指令try_files

try_files指令是按顺序检测文件的存在性,并且返回第一个找到文件的内容,如果第一个找不到就会自动找第二个,依次查找.其实现的是内部跳转.以下举例说明: 案例1(跳转到变量): server {   listen 8000;   server_name 121.10.143.66;   root html;   index index.html index.php; location /abc { try_files /4.html /5.html @qwe;      --检测文件4.ht

转:Nginx配置指令location匹配符优先级和安全问题

转:http://www.jb51.net/article/47761.htm 使用nginx 很久了,它的性能高,稳定性表现也很好,得到了很多人的认可.特别是它的配置,有点像写程序一样,每行命令结尾一个";"号,语句块用"{}"括起来. 配制好,直接nginx -t 检查配制情况,配制成功,直接运行:service nginx reload .服务器没有任何宕机情况下,实现平稳修改配置 最近一直在做location 配置,遇到优先级别问题(如果配置不当可能存在安全

JFinal 配置类 方法执行顺序

1.public void configConstant(Constants me) 常量配置方法,一般 在里面 读取 配置文件 2.public void configRoute(Routes me) 配置路由,如下 me.add("/", IndexController.class, "/index"); // 第三个参数为该Controller的视图存放路径 me.add("/blog", BlogController.class); //