Nginx执行阶段(3)

在 any 方式下,access 阶段只要有一个模块通过了验证,就会认为请求整体通过了验证,而在上例中, ngx_lua 模块的 access_by_lua 语句总是会通过验证的。

ngx_index 模块, ngx_autoindex 模块,以及 ngx_static 模块

Nginx 一般会在 content 阶段安排三个这样的静态资源服务模块。按照它们在 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; }

为了进一步确认 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

如果此时把 /var/www/index.html 文件删除,再访问 / 又会发生什么事情呢?答案是返回 403 Forbidden 出错页。为什么呢?因为 ngx_index 模块找不到 index 指令指定的文件(在这里就是 index.html),接着把处理权转给 content 阶段的后续模块,而后续的模块也都无法处理这个请求,于是 Nginx 只好放弃,输出了错误页
运行在 ngx_index 模块之后的 ngx_autoindex 模块就可以用于自动生成这样的“目录索引”网页。我们来把上例修改一下:

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

此时仍然保持文件系统中的 /var/www/index.html 文件不存在。我们再访问 / 位置时,就会得到一张漂亮的网页:

$ curl 'http://localhost:8080/'

ngx_static 模块服务磁盘文件的例子。我们使用下面这个配置片段:
location / {
root /var/www/;
}

现在来通过 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-Type、Content-Length 以及 Last-Modified 等响应头。

很多初学者会想当然地把 404 错误理解为某个 location 不存在,其实上面这个例子表明,即使 location 存在并成功匹配,也是可能返回 404 错误页的。因为决定着 404 错误页的是抽象的“资源”是否存在,而非某个具体的 location 是否存在。
location /auth {
access_by_lua '
';
}
显然,这个 /auth 接口只定义了 access 阶段的配置指令,即 access_by_lua,并未定义任何 content 阶段的配置指令。于是当我们请求 /auth 接口时,在 access 阶段的 Lua 代码会如期执行,然后 content 阶段的那些静态文件服务会紧接着自动发生作用,直至 ngx_static 模块去文件系统上找名为 auth 的文件。而经常地,404 错误页会抛出,除非运气太好,在对应路径上确实存在一个叫做 auth 的文件。所以,一条经验是,当遇到意外的 404 错误并且又不涉及静态文件服务时,应当首先检查是否在对应的 location 配置块中恰当地配置了 content 阶段的模块指令,例如 content_by_lua、 echo 以及 proxy_pass 之类。

openresty请求处理顺序

set_by_lua: 流程分支处理判断变量初始化
rewrite_by_lua: 转发、重定向、缓存等功能(例如特定请求代理到外网)
access_by_lua: IP 准入、接口权限等情况集中处理(例如配合 iptable 完成简单防火墙)
content_by_lua: 内容生成
header_filter_by_lua: 响应头部过滤处理(例如添加头部信息)
body_filter_by_lua: 响应体过滤处理(例如完成应答内容统一成大写) log_by_lua*:会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器)

在这里插入图片描述

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/4c70bd71a3b2b805f7f666a3a46bac2f.html