转载自 http://blog.sina.com.cn/openresty
前面我们在 (五) 中提到,在一个 location 中使用 content 阶段指令时,通常情况下就是对应的 Nginx 模块注册该 location 中的“内容处理程序”。那么当一个 location 中未使用任何 content 阶段的指令,即没有模块注册“内容处理程序”时,content 阶段会发生什么事情呢?谁又来担负起生成内容和输出响应的重担呢?答案就是那些把当前请求的 URI 映射到文件系统的静态资源服务模块。当存在“内容处理程序”时,这些静态资源服务模块并不会起作用;反之,请求的处理权就会自动落到这些模块上。
Nginx 一般会在 content 阶段安排三个这样的静态资源服务模块(除非你的 Nginx 在构造时显式禁用了这三个模块中的一个或者多个,又或者启用了这种类型的其他模块)。按照它们在 content 阶段的运行顺序,依次是 ngx_index 模块,ngx_autoindex 模块,以及 ngx_static 模块。下面就来逐一介绍一下这三个模块。
ngx_index 和 ngx_autoindex 模块都只会作用于那些 URI 以 / 结尾的请求,例如请求 GET /cats/,而对于不以 / 结尾的请求则会直接忽略,同时把处理权移交给 content 阶段的下一个模块。而 ngx_static 模块则刚好相反,直接忽略那些 URI 以 / 结尾的请求。
ngx_index 模块主要用于在文件系统目录中自动查找指定的首页文件,类似 index.html 和 index.htm 这样的,例如:
location / {
root /var/www/;
index index.htm index.html;
}
这样,当用户请求 / 地址时,Nginx 就会自动在 root 配置指令指定的文件系统目录下依次寻找 index.htm 和 index.html 这两个文件。如果 index.htm 文件存在,则直接发起“内部跳转”到 /index.htm 这个新的地址;而如果 index.htm 文件不存在,则继续检查 index.html 是否存在。如果存在,同样发起“内部跳转”到 /index.html;如果 index.html 文件仍然不存在,则放弃处理权给 content 阶段的下一个模块。
我们前面已经在 Nginx 变量漫谈(二) 中提到, echo_exec 指令和 rewrite 指令可以发起“内部跳转”。这种跳转会自动修改当前请求的 URI,并且重新匹配与之对应的 location 配置块,再重新执行 rewrite、access、content 等处理阶段。因为是“内部跳转”,所以有别于 HTTP 协议中定义的基于 302 和 301 响应的“外部跳转”,最终用户的浏览器的地址栏也不会发生变化,依然是原来的 URI 位置。而 ngx_index 模块一旦找到了 index 指令中列举的文件之后,就会发起这样的“内部跳转”,仿佛用户是直接请求的这个文件所对应的 URI 一样。
为了进一步确认 ngx_index 模块在找到文件时的“内部跳转”行为,我们不妨设计下面这个小例子:
location / {
root /var/www/;
index index.html;
}
location /index.html {
set $a 32;
echo "a = $a";
}
此时我们在本机的 /var/www/ 目录下创建一个空白的 index.html 文件,并确保该文件的权限设置对于运行 Nginx worker 进程的帐户可读。然后我们来请求一下根位置(/):
$ curl 'http://localhost:8080/'
a = 32
这里发生了什么?为什么输出不是 index.html 文件的内容(即空白)?首先对于用户的原始请求 GET /,Nginx 匹配出 location / 来处理它,然后 content 阶段的 ngx_index 模块在 /var/www/ 下找到了 index.html,于是立即发起一个到 /index.html 位置的“内部跳转”。
到这里,相信大家都不会有问题。接下来有趣的事情发生了!在重新为 /index.html 这个新位置匹配 location 配置块时,location /index.html 的优先级要高于 location /,因为 location 块按照 URI 前缀来匹配时遵循所谓的“最长子串匹配语义”。这样,在进入 location /index.html 配置块之后,又重新开始执行 rewrite 、access、以及 content 等阶段。最终输出 a = 32 自然也就在情理之中了。
我们接着研究上面这个例子。如果此时把 /var/www/index.html 文件删除,再访问 / 又会发生什么事情呢?答案是返回 403 Forbidden 出错页。为什么呢?因为 ngx_index 模块找不到 index 指令指定的文件(在这里就是 index.html),接着把处理权转给 content 阶段的后续模块,而后续的模块也都无法处理这个请求,于是 Nginx 只好放弃,输出了错误页,并且在 Nginx 错误日志中留下了类似这一行信息:
[error] 28789#0: *1 directory index of "/var/www/" is forbidden
所谓 directory index 便是生成“目录索引”的意思,典型的方式就是生成一个网页,上面列举出 /var/www/ 目录下的所有文件和子目录。而运行在 ngx_index 模块之后的 ngx_autoindex 模块就可以用于自动生成这样的“目录索引”网页。我们来把上例修改一下:
location / {
root /var/www/;
index index.html;
autoindex on;
}
此时仍然保持文件系统中的 /var/www/index.html 文件不存在。我们再访问 / 位置时,就会得到一张漂亮的网页:
$ curl 'http://localhost:8080/'
<html>
<head><title>Index of /</title></head>
<body bgcolor="white">
<h1>Index of /</h1><hr><pre><a href="../">../</a>
<a href="cgi-bin/">cgi-bin/</a> 08-Mar-2010 19:36 -
<a href="error/">error/</a> 08-Mar-2010 19:36 -
<a href="htdocs/">htdocs/</a> 05-Apr-2010 03:55 -
<a href="icons/">icons/</a> 08-Mar-2010 19:36 -
</pre><hr></body>
</html>
生成的 HTML 源码显示,我本机的 /var/www/ 目录下还有 cgi-bin/, error/, htdocs/, 以及 icons/ 这几个子目录。在你的系统中尝试上面的例子,输出很可能会不太一样。
值得一提的是,当你的文件系统中存在 /var/www/index.html 时,优先运行的 ngx_index 模块就会发起“内部跳转”,根本轮不到 ngx_autoindex 执行。感兴趣的读者可以自己测试一下。
在 content 阶段默认“垫底”的最后一个模块便是极为常用的 ngx_static 模块。这个模块主要实现服务静态文件的功能。比方说,一个网站的静态资源,包括静态 .html 文件、静态 .css 文件、静态 .js 文件、以及静态图片文件等等,全部可以通过这个模块对外服务。前面介绍的 ngx_index 模块虽然可以在指定的首页文件存在时发起“内部跳转”,但真正把相应的首页文件服务出去(即把该文件的内容作为响应体数据输出,并设置相应的响应头),还是得靠这个 ngx_static 模块来完成。
相关推荐
总结来说,理解Nginx Rewrite模块的执行顺序对于优化和调试Nginx配置至关重要。正确地编写和组织Rewrite规则可以确保Nginx服务器高效、稳定地处理各种URL请求。在实际应用中,要特别注意避免重写规则引起的循环和...
2. **选择处理模块**:Nginx基于配置文件中的location指令,选择合适的处理模块来处理请求。 3. **负载均衡**:如果配置了负载均衡,负载均衡模块会根据策略选择一个后端服务器。 4. **处理请求**:处理模块执行其...
4. **root** 和 **index**:root指令定义静态文件的根目录,index指令定义自动索引文件的顺序。 5. **server_name**:定义服务器的域名或IP。 6. **location**:使用正则表达式或精确匹配,根据URI路由请求。 7. **...
配置指令的执行顺序也会影响最终的Nginx行为。 由于Nginx的配置涉及多方面的知识,因此教程的连载计划一般会从基础开始,逐步深入到高级主题。例如,在“Nginx新手起步”中,可能涵盖了最基础的安装和配置流程,而...
**Nginx 配置指南** Nginx 是一款高性能的 Web 服务器和反向代理服务器,被广泛用于处理静态内容、动态内容分发以及负载均衡。...通过合理配置,Nginx 可以为你的 Web 应用提供稳定、高效的负载均衡服务。
然后,需要配置root指令,该指令指定了请求的根目录,Nginx会在这些目录下查找请求的静态文件。对于静态文件的请求,Nginx会直接从文件系统中读取并返回给客户端,无需经过复杂的处理。配置location块可以为不同的...
轮询是Nginx的默认负载均衡策略,请求按照时间顺序逐一分配到不同的服务器。如果某台服务器down掉,会自动从服务器组中剔除,等该服务器恢复后,再将其加入到服务器组中。 2. 最少连接策略 最少连接策略会将新的...
- 静态文件服务:通过配置`root`和`index`指令,Nginx可以直接提供静态文件服务。 - 反向代理:使用`proxy_pass`将请求转发至后端服务器,实现负载均衡或隐藏真实服务器。 - 负载均衡:结合`upstream`模块,可以...
4. **指令顺序**:配置文件中的指令执行顺序对结果有影响,一般是从上到下依次解析。 **核心配置模块** 1. **http模块**:定义全局设置,如日志格式、文件路径等。 2. **server模块**:定义一个监听的网络端口,...
教程内容包括但不限于Nginx变量使用、配置指令执行顺序、子请求处理、静态文件服务、日志服务以及与其他服务(如Memcached、Redis、MySQL、PostgreSQL等)的集成。该教程还涉及了安全和访问控制的相关内容。 该教程...
3. **指令执行顺序**:Nginx在处理请求时,会按照以下顺序执行配置指令: - 首先执行全局块中的指令。 - 然后是events块内的指令。 - 接着是http块中的指令。 - 最后根据请求的端口找到对应的server块,并执行...
Nginx可以通过`proxy_cache`指令实现静态资源的缓存,提高响应速度,减轻后端服务器压力。配置包括定义缓存区、缓存策略以及缓存更新规则。 ### 五、Nginx安全配置 1. **防盗链(防盗链配置)**:通过`valid_...
6. **配置Nginx使用iconv模块**:在Nginx的配置文件(通常是`nginx.conf`)中,添加`load_module`指令来加载`iconv`模块的`.so`文件,例如:`load_module modules/ngx_http_iconv_module.so;`。 7. **重启Nginx**:...
1. **开启缓存**:使用proxy_cache指令开启缓存,提高静态资源的访问速度。 2. **缓存策略**:可设置缓存大小、有效期、缓存清理等策略,优化缓存效果。 3. **缓存失效**:通过proxy_cache_bypass和proxy_no_cache...
这些指令可以在Nginx的配置文件中设置,并在启动时被解析到相应的模块配置结构体中。 **示例**:定义一个简单的指令: ```c static ngx_command_t my_commands[] = { { ngx_string("my_module_value"), ngx_conf...
这部分教程解释了Nginx配置文件中指令的执行顺序及其背后的逻辑。正确理解指令的执行流程对于调试配置问题至关重要。 - **层级结构**:介绍了Nginx配置文件的基本结构,包括HTTP块、Server块、Location块等,并解释...
- **请求处理**:当客户端发起请求时,Nginx的工作进程会按照一定的逻辑顺序执行各个模块的功能。 - **模块化体系结构**:Nginx的模块化体系是其核心设计之一,每个模块负责特定的功能。 - **模块概述**:Nginx中...