nginx系列第八篇:Ubuntu下验证nginx各请求处理阶段

Nginx处理请求的过程一共划分为11个阶段,按照执行顺序依次是 post-read、server-rewrite、find-config、rewrite、post-rewrite、preaccess、access、post-access、try-files、content 以及 log。

准备工作:host文件加入测试域名

sudo vi /etc/hosts

加入:

127.0.0.1 www.liudehua.com

目录

[阶段一 POST_READ](#阶段一 POST_READ)

[阶段二 SERVER_REWRITE](#阶段二 SERVER_REWRITE)

[阶段三 FIND_CONFIG](#阶段三 FIND_CONFIG)

[阶段四 REWRITE](#阶段四 REWRITE)

[阶段五 POST_REWRITE](#阶段五 POST_REWRITE)

[阶段六 PREACCESS](#阶段六 PREACCESS)

[阶段七 ACCESS](#阶段七 ACCESS)

[阶段八 POST_ACCESS](#阶段八 POST_ACCESS)

[阶段九 TRY_FILES](#阶段九 TRY_FILES)

[阶段十 CONTENT](#阶段十 CONTENT)

[阶段十一 LOG阶段](#阶段十一 LOG阶段)


阶段一 POST_READ

POST_READ阶段是nginx处理请求流程中第一个可以添加模块函数的阶段,任何需要在接收完请求头之后立刻处理的逻辑可以在该阶段注册处理函数。

nginx源码中只有realip模块在该阶段注册了函数,当nginx前端多了一个7层负载均衡层,并且客户端的真实ip被前端保存在请求头中时,该模块用来将客户端的ip替换为请求头中保存的值。

realip模块之所以在POST_READ阶段执行的原因是它需要在其他模块执行之前悄悄的将客户端ip替换为真实值,而且它需要的信息仅仅只是请求头。一般很少有模块需要注册在POST_READ阶段,realip模块默认没有编译进nginx。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

set_real_ip_from 127.0.0.1;

real_ip_header x-real-ip;

location / {

set $addr $remote_addr;

return 200 "real-ip: $addr";

}

}

错误:

nginx: [emerg] unknown directive "set_real_ip_from"

解决办法:加入realip模块重新编译

sudo ./configure --prefix=/home/tiger/nginx-1.22.1/nginx --with-stream --with-http_realip_module

sudo make & make install

测试请求:

curl -H "x-real-ip: 1.2.3.4" http://www.liudehua.com/

real-ip: 1.2.3.4

说明:

curl 工具的 -H 选项指定了额外的 HTTP 请求头

阶段二 SERVER_REWRITE

SERVER_REWRITE阶段是nginx中第一个必须经历的重要phase,请求进入此阶段时已经找到对应的虚拟主机(server)配置。在SERVER_REWRITE阶段中,请求还未被匹配到一个具体的location中。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

location /server_rewrite {

set b "a, hello world";

return 200 "args: $b";

}

set $a test_server_rewrite;

}

请求:

curl http://www.liudehua.com/server_rewrite

响应:

args: test_server_rewrite, hello world

阶段三 FIND_CONFIG

FIND_CONFIG阶段是寻找配置,是根据uri查找location配置。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

location / {

return 200 "test FIND_CONFIG";

}

}

curl http://www.liudehua.com

test FIND_CONFIG

阶段四 REWRITE

REWRITE阶段为location级别的重写。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

location /rewrite {

root /home/tiger/nginx-1.22.1/nginx/html;

rewrite . /rewrite/index.txt break;

}

}

请求:

curl http://www.liudehua.com/rewrite

响应:

^^ ^^ ^_^ hello rewrite

阶段五 POST_REWRITE

该阶段不能注册handler,仅仅只是检查上一阶段是否做了uri重写,如果没有重写的话,直接进入下一阶段;如果有重写的话,则利用next跳转域往前跳转到FIND_CONFIG阶段重新执行。Nginx对uri重写次数做了限制,默认是10次

阶段六 PREACCESS

该阶段表明Nginx已经将请求确定到了某一个location(当该server没有任何location时,也可能是server),该阶段一般用来做资源控制,默认情况下,诸如ngx_http_limit_conn_module,ngx_http_limit_req_module等模块会在该阶段注册handler,

用于控制连接数,请求速率等。PREACCESS阶段使用的checker是默认的ngx_http_core_generic_phase函数。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

location /post_rewrite {

root /home/tiger/nginx-1.22.1/nginx/html;

limit_conn addr 1; #允许请求连接数

limit_rate 1k; #限定网络传输速率

}

}

错误:

nginx: [emerg] zero size shared memory zone "addr"

解决办法:加入zone模块重新编译

server标签同级别增加如下配置

limit_conn_zone $binary_remote_addr zone=addr:10m;

请求:

curl http://www.liudehua.com/post_rewrite

阶段七 ACCESS

该阶段的首要目的是做权限控制,默认情况下Nginx的ngx_http_access_module和ngx_http_auth_basic_module模块分别会在该阶段注册一个handler。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

auth_basic "User Authentication";

auth_basic_user_file /etc/nginx/.passwd-www;

location / {

root /home/tiger/nginx-1.22.1/nginx/html;

index index.html;

}

}

测试:安装工具htpasswd

sudo apt install apache2-utils

添加认证文件:

htpasswd -c /home/tiger/nginx-1.22.1/nginx/html/.passwd-www www

浏览器访问:

http://www.liudehua.com/

阶段八 POST_ACCESS

POST_ACCESS和POST_REWRITE阶段一样,只是处理一下上一阶段的结果,而不能挂载自己的handler,具体为如果ACCESS阶段返回了NGX_HTTP_FORBIDDEN或NGX_HTTP_UNAUTHORIZED(记录在r->access_code字段),该阶段会结束掉请求。

阶段九 TRY_FILES

TRY_FILES阶段仅当配置了try_files指令时生效,实际上该指令不常用,它的功能是指定一个或者多个文件或目录,最后一个参数可以指定为一个location或一个返回码,当设置了该指令时,TRY_FILES阶段调用checker函数ngx_http_core_try_files_phase来依此检查指定的文件或目录是否存在,如果本地文件系统存在某个文件或目录则退出该阶段继续执行下面的阶段,否则内部重定向到最后一个参数指定的location或返回指定的返回码。

该阶段也不能注册handler

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

location / {

root /home/tiger/nginx-1.22.1/nginx/html;

try_files $uri /test.html /index.htm /index.html;

}

}

以上配置会按顺序检查文件是否存在,顺序:$uri -> /test.html -> /index.htm -> /index.html

阶段十 CONTENT

CONTENT 阶段任务是生成响应内容并输出HTTP响应。

content阶段包含三个静态资源服务模块,ngx_index,ngx_autoindex,ngx_static用于当在location未使用任何content阶段的指令时处理URL请求。ngx_index和ngx_autoindex只作用于已/结尾的URI,其他由ngx_static执行。

ngx_index使用index指令用于查找首页文件,配合root指令实现,当找到文件后触发内部跳转而不是直接返回该文件,若都不存在则返回403。

nginx配置文件:

server {

listen 80;

server_name www.liudehua.com;

root /home/tiger/nginx-1.22.1/nginx/html;

location / {

index index.txt;

}

}

请求:

curl http://www.liudehua.com/

响应:

fdsssssssssssss

42333333

5433333333333

阶段十一 LOG阶段

LOG阶段主要的目的就是记录访问日志,进入该阶段表明该请求的响应已经发送到系统发送缓冲区。另外这个阶段的handler链实际上并不是在ngx_http_core_run_phases函数中执行,而是在释放请求资源的ngx_http_free_request函数中运行,这样做的原因实际是为了简化流程,因为ngx_http_core_run_phases可能会执行多次,而LOG阶段只需要再请求所有逻辑都结束时运行一次,所以在ngx_http_free_request函数中运行LOG阶段的handler链是非常好的选择。

备注:参考

https://www.cnblogs.com/imcati/p/11681392.html

相关推荐
苹果醋36 小时前
Golang的文件加密工具
运维·vue.js·spring boot·nginx·课程设计
苹果醋316 小时前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
苹果醋31 天前
React源码02 - 基础知识 React API 一览
java·运维·spring boot·mysql·nginx
阿松哥哥20181 天前
linux环境使用源码方式安装nginx(centos)
linux·nginx·centos
与君共勉121382 天前
Nginx 负载均衡的实现
运维·服务器·nginx·负载均衡
okok__TXF2 天前
Nginx + Lua脚本打配合
nginx·lua
青灯文案12 天前
前端 HTTP 请求由 Nginx 反向代理和 API 网关到后端服务的流程
前端·nginx·http
小屁不止是运维2 天前
麒麟操作系统服务架构保姆级教程(五)NGINX中间件详解
linux·运维·服务器·nginx·中间件·架构
恩爸编程2 天前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
努力--坚持2 天前
电商项目-网站首页高可用(一)
nginx·lua·openresty