48 | 详解HTTP请求的11个阶段
出http过滤模块和只提供变量的nginx模块之外,所有的http模块从nginx定义好的11个阶段进行请求的处理。所以每一个http模块何时生效,有没有机会生效。要看一个请求究竟处理到哪个阶段。nginx究竟如何定义这11个阶段的?
HTTP请求处理时的11个阶段
image.png
先看左边的示意图:
Read Request Header: 当一个请求进入到黄色框(nginx之中的时候),首先,Read Request Header,读取到请求的头部,并且决定使用哪个server块上面配置指令处理请求。前面几节讲的流程全部在Read Request Header中。所以,这个时候我们已经知道所有指令的值如何被使用(当然location中还没有决定)。从下面开始进入到11个处理阶段中了。
Configuration Block:寻找哪个location生效了。
Apply Rate Limits:然后是否决定要对它限速。
Perform Authentication:然后做些验证。根据referer等等字段判断,这是否是一种盗链的请求,或者用auth basic 协议验证下用户的请求权限。
Generate Content:然后生成返回给用户的响应。
Updsteam Services:为了生成这个响应呢。可能作为反向代理的时候,要和上游服务进行通讯,把上游发的作为响应的内容。
Internal redirects and subrequests:Configuration Block
、Apply Rate Limits
、Perform Authentication
、Generate Content
,这四步过程中可能会发生重定向或字请求。这时候又会走这样的一个过程。
Response Filters:在向用户返回响应的时候,要经过过滤模块。比如:使用gzip做下压缩。
Log:在返回给用户时候,记录下日志。
实际流程看右边的图
实际的流程跟示意图不同,但大致相似。
POST_READ:read到header所有请求头部之后。当读完http头部,没有做任何再加工之前,获取到一些原始值。
SERVER_REWRITE跟REWRITE:都只有一个模块。一般没有第三方模块处理这个阶段的。
FIND_CONFIG:只有nginx的框架会做。这个阶段没有任何http模块在这个阶段中。这个阶段在做location的匹配。
POST_REWRITE:在刚刚rewrite 之后要做的一些事情。
access相关的三个模块,确认访问权限,为什么定义三个模块
PREACCESS:在access之前要不要做些工作。比如限速。
ACCESS:核心解决的是能不能访问。auth_basic根据用户的账号密码,access能是根据用户的访问IP,auth_request根据第三方服务返回是否可以访问。
POSTACCESS:在access之后要不要做些事情。
PRECONTENT:在处理content之前,比如mirrors。比如怎么样往一个请求产生多个子请求,mirrors就是干这些事情的。
CONTENT:干的比较多。
LOG: 记录日志。
49 | 11个阶段的顺序处理
当一个http请求进入这11个阶段时,由于每个阶段有零个或多个http模块。如果某一个模块不在把一个请求向下传递,后面的模块是得不到执行的。同一个阶段多个模块并不一定每个模块都有机会执行到。可能会有前面的模块把请求传递给下一个阶段中的模块去处理。
11个阶段顺序处理
image.png
这里每一个模块都属于某一个阶段,每一个阶段之间,这些模块都是有序的。这个顺序如何能得到呢?我们去看nginx_module.c
。编译后这些添加的模块都会在ngx_module_names数组中出现。它们出现的位置顺序非常关键。
我们看到数组中比如limit_conn_module在limit_req_module上面(它两同属于preaccess阶段),但是实际处理是与这个配置相反的。也就是先被limit_req处理后被limit_conn处理。当它们两个同时生效取阻止一个请求的时候,假设它们的返回值不同,limit_connect是没有机会得到执行的,因为limit_req先于limit_connect把请求的结果返回给用户了。 其他所有的模块都一样。在之前课程中有个同学遇到一个问题。说auto_index没有展示响应的目录结构而是显示了index.html的内容。这里的原因就是index先于auto_index生效,所以先返回了index.html内容。
像灰色那三个是nginx框架执行的,其他第三方nginx模块没有机会在这里得到执行。
在有的阶段,也有可能不按照这样的顺序。比如说在access阶段中,有一个指令叫做satisfy指令,它可以指示当某一个满足,比如access满足直接跳到try_files而不会去执行auth_basic、auth_request。当content阶段中,比如:index模块执行了,它会直接跳到log阶段,而不会执行auto_index跟static。
作者:言十年
链接:https://www.jianshu.com/p/50bfaf6eec82
共同学习,写下你的评论
评论加载中...
作者其他优质文章