Nginx 处理一个 HTTP 请求的全过程
前面给大家讲了 Nginx 是如何处理 HTTP请求头部的,接下来就到了真正处理 HTTP 请求的阶段了。先看下面这张图,这张图是 Nginx 处理 HTTP 请求的示意图,虽然简单,但是却很好的说明了整个过程。
- Read Request Headers:解析请求头。
- Identify Configuration Block:识别由哪一个 location 进行处理,匹配 URL。
- Apply Rate Limits:判断是否限速。例如可能这个请求并发的连接数太多超过了限制,或者 QPS 太高。
- Perform Authentication:连接控制,验证请求。例如可能根据 Referrer 头部做一些防盗链的设置,或者验证用户的权限。
- Generate Content:生成返回给用户的响应。为了生成这个响应,做反向代理的时候可能会和上游服务(Upstream Services)进行通信,然后这个过程中还可能会有些子请求或者重定向,那么还会走一下这个过程(Internal redirects and subrequests)。
- Response Filters:过滤返回给用户的响应。比如压缩响应,或者对图片进行处理。
- Log:记录日志。
以上这七个步骤从整体上介绍了一下处理流程,下面还会再说一下实际的处理过程。
Nginx 处理 HTTP 请求的 11 个阶段
下面介绍一下详细的 11 个阶段,每个阶段都可能对应着一个甚至多个 HTTP 模块,通过这样一个模块对比,我们也能够很好的理解这些模块具体是怎么样发挥作用的。
- POST_READ:在 read 完请求的头部之后,在没有对头部做任何处理之前,想要获取到一些原始的值,就应该在这个阶段进行处理。这里面会涉及到一个 realip 模块。
- SERVER_REWRITE:和下面的 REWRITE 阶段一样,都只有一个模块叫 rewrite 模块,一般没有第三方模块会处理这个阶段。
- FIND_CONFIG:做 location 的匹配,暂时没有模块会用到。
- REWRITE:对 URL 做一些处理。
- POST_WRITE:处于 REWRITE 之后,也是暂时没有模块会在这个阶段出现。
接下来是确认用户访问权限的三个模块:
- PREACCESS:是在 ACCESS 之前要做一些工作,例如并发连接和 QPS 需要进行限制,涉及到两个模块:limt_conn 和 limit_req (http请求会先被limit_req处理再被limit_conn处理,当两个同时生效去阻止一个请求的时候,假设两个的返回值不同,因为limit_req先于limit_conn把请求的结果返回给用户了)
- ACCESS:核心要解决的是用户能不能访问的问题,例如 auth_basic 是用户名和密码,access 是用户访问 IP,auth_request 根据第三方服务返回是否可以去访问。
- POST_ACCESS:是在 ACCESS 之后会做一些事情,同样暂时没有模块会用到。
最后的三个阶段处理响应和日志:
-
PRECONTENT:在处理 CONTENT 之前会做一些事情,例如会把子请求发送给第三方的服务去处理,try_files 模块也是在这个阶段中。
-
CONTENT:这个阶段涉及到的模块就非常多了,例如 index, autoindex, concat 等都是在这个阶段生效的。
-
LOG:记录日志 access_log 模块。
以上的这些阶段都是严格按照顺序进行处理的,当然,每个阶段中各个 HTTP 模块的处理顺序也很重要,如果某个模块不把请求向下传递,后面的模块是接收不到请求的。而且每个阶段中的模块也不一定所有都要执行一遍,下面就接着讲一下各个阶段模块之间的请求顺序。
11 个阶段的顺序处理
当http请求进入这11个阶段的时候,由于每个阶段可能会有1个或者多个http模块,如果某个模块不再把请求向下传递,后面的模块是得不到执行的,同一个阶段并不是每个模块都有机会被执行到,可能会有前面阶段的模块把请求传递给下一个阶段当中的模块处理
如下图所示,每一个模块处理之间是有序的,那么这个顺序怎么才能得到呢?其实非常简单,在源码 ngx_module.c 中,有一个数组 ngx_module_name
,其中包含了在编译 Nginx 的时候的 with 指令所包含的所有模块,它们之间的顺序非常关键,在数组中顺序是相反的。(./configure当中使用--with,或者--without来添加或者移除模块或者--add-modules来添加第三方模块,这些模块添加完之后都会在上面的ngx_module_names[] 数组当中出现,出现的位置和顺序都非常关键)
[root@www ~]# cd /usr/src/nginx-1.16.1/objs/
autoconf.err nginx ngx_auto_config.h ngx_modules.c src/
Makefile nginx.8 ngx_auto_headers.h ngx_modules.o
[root@www ~]# cd /usr/src/nginx-1.16.1/objs/
[root@www objs]# ls ngx_modules.c
ngx_modules.c
[root@www objs]# cat ngx_modules.c
char *ngx_module_names[] = {
… …
"ngx_http_static_module",
"ngx_http_autoindex_module",
"ngx_http_index_module",
"ngx_http_random_index_module",
"ngx_http_mirror_module",
"ngx_http_try_files_module",
"ngx_http_auth_request_module",
"ngx_http_auth_basic_module",
"ngx_http_access_module",
"ngx_http_limit_conn_module",
"ngx_http_limit_req_module",
"ngx_http_realip_module",
"ngx_http_referer_module",
"ngx_http_rewrite_module",
"ngx_http_concat_module",
… …
}
灰色部分的模块是 Nginx 的框架部分去执行处理的,第三方模块没有机会在这里得到处理。
在依次向下执行的过程中,也可能不按照这样的顺序。例如,在 access 阶段中,有一个指令叫 satisfy,它可以指示当有一个满足的时候就直接跳到下一个阶段进行处理,例如当 access 满足了,就直接跳到 try_files 模块进行处理,而不会再执行 auth_basic、auth_request 模块。
在 content 阶段中,当 index 模块执行了,就不会再执行 auto_index 模块,而是直接跳到 log 模块。(为什么autoindex没有展示相应的目录结构,而显示了index.html里面的内容,这里的原因就是因为index模块先于auto_index模块生效了)
整个 11 个阶段所涉及到的模块和先后顺序如下图所示:(这样的顺序依次向下执行的时候向rewrite,find_config,rewrite这些是nginx HTTP框架去执行的,其他的nginx模块没有机会在这执行。)
相关文章
- 敏感信息直接在 nginx 通过环境变量设置
- centos7系统下安装php-fpm并配置nginx支持并开启网站gzip压缩
- nginx:413 Request Entity Too Large 及 修改 PHP上传文件大小配置
- windows 下 nginx 的启动 停止 关闭
- nginx 413 500报错
- Nginx Tutorial #1: Basic Concepts(转)
- 为nginx增加nginx_http_concat模块
- 高并发 Nginx+Lua OpenResty系列(11)——流量复制/AB测试/协程
- nginx打开目录浏览
- nginx重新整理——————http请求的11个阶段中的content阶段[十八]
- nginx重新整理——————http请求的11个阶段中的preaccess[十四]
- nginx重新整理——————http请求的11个阶段中的find_config[十三]
- nginx集群:nginx配置负载均衡集群(nginx1.18.0)
- Nginx编译安装第三方模块http_substitutions_filter_module
- OpenResty(Nginx)+Lua+GraphicsMagick实现缩略图功能
- Nginx HTTP 请求头中的 X-Forwarded-For
- Nginx content阶段 http-concat-master模块提升多个小文件性能
- k8s部署ingress:使用heptio-contour部署ingress controller(通过sealos安装,非nginx-ingress类型)
- nginx负载均衡配置
- nginx 、vue - nginx同一个端口配置多个vue工程 和 vue 配套打包具体配置 教程
- nginx proxy_set_header Host $host 和 proxy_set_header Host $http_host 的作用对比
- Nginx实现XSS、SQL注入防护 —— 筑梦之路
- Ubuntu Nginx 搭建文件下载服务器
- ubutun中安装nginx
- nginx配置laravel lumen重写
- nginx转发
- Linux系统如何查看nginx安装目录