注册用户享全站资源 并成为粉丝 不定时福利发放
 

Nginx请求处理流程你了解吗?

22
发表时间:2018-12-22 12:44

本文主要介绍了nginx的11个处理阶段和lua的8个处理阶段,并说明了nginx和lua运行阶段的对应关系。

一、nginx 11 个处理阶段

nginx实际把http请求处理流程划分为了11个阶段,这样划分的原因是将请求的执行逻辑细分,以模块为单位进行处理,各个阶段可以包含任意多个HTTP模块并以流水线的方式处理请求。这样做的好处是使处理过程更加灵活、降低耦合度。这11个HTTP阶段如下所示:

1)NGX_HTTP_POST_READ_PHASE:

接收到完整的HTTP头部后处理的阶段,它位于uri重写之前,实际上很少有模块会注册在该阶段,默认的情况下,该阶段被跳过。

2)NGX_HTTP_SERVER_REWRITE_PHASE:

URI与location匹配前,修改URI的阶段,用于重定向,也就是该阶段执行处于server块内,location块外的重写指令,在读取请求头的过程中nginx会根据host及端口找到对应的虚拟主机配置。

3)NGX_HTTP_FIND_CONFIG_PHASE:

根据URI寻找匹配的location块配置项阶段,该阶段使用重写之后的uri来查找对应的location,值得注意的是该阶段可能会被执行多次,因为也可能有location级别的重写指令。

4)NGX_HTTP_REWRITE_PHASE:

上一阶段找到location块后再修改URI,location级别的uri重写阶段,该阶段执行location基本的重写指令,也可能会被执行多次。

5)NGX_HTTP_POST_REWRITE_PHASE:

防止重写URL后导致的死循环,location级别重写的后一阶段,用来检查上阶段是否有uri重写,并根据结果跳转到合适的阶段。

6)NGX_HTTP_PREACCESS_PHASE:

下一阶段之前的准备,访问权限控制的前一阶段,该阶段在权限控制阶段之前,一般也用于访问控制,比如限制访问频率,链接数等。

7)NGX_HTTP_ACCESS_PHASE:

让HTTP模块判断是否允许这个请求进入Nginx服务器,访问权限控制阶段,比如基于ip黑白名单的权限控制,基于用户名密码的权限控制等。

8)NGX_HTTP_POST_ACCESS_PHASE:

访问权限控制的后一阶段,该阶段根据权限控制阶段的执行结果进行相应处理,向用户发送拒绝服务的错误码,用来响应上一阶段的拒绝。

9)NGX_HTTP_TRY_FILES_PHASE:

为访问静态文件资源而设置,try_files指令的处理阶段,如果没有配置try_files指令,则该阶段被跳过。

10)NGX_HTTP_CONTENT_PHASE:

处理HTTP请求内容的阶段,大部分HTTP模块介入这个阶段,内容生成阶段,该阶段产生响应,并发送到客户端。

11)NGX_HTTP_LOG_PHASE:

处理完请求后的日志记录阶段,该阶段记录访问日志。

以上11个阶段中,HTTP无法介入的阶段有4个:

3)NGX_HTTP_FIND_CONFIG_PHASE

5)NGX_HTTP_POST_REWRITE_PHASE

8)NGX_HTTP_POST_ACCESS_PHASE

9)NGX_HTTP_TRY_FILES_PHASE

剩余的7个阶段,HTTP模块均能介入,每个阶段可介入模块的个数也是没有限制的,多个HTTP模块可同时介入同一阶段并作用于同一请求。

HTTP阶段的定义,包括checker检查方法和handler处理方法,如下所示

一个http{}块解析完毕后,将会根据nginx.conf中的配置产生由ngx_http_phase_handler_t组成的数组,在处理HTTP请求时,一般情况下这些阶段是顺序向后执行的,但ngx_http_phase_handler_t中的next成员使得它们也可以非顺序地执行,ngx_http_phase_engine_t结构体就是所有ngx_http_phase_handler_t组成的数组,如下所示:

可以看到,ngx_http_phase_engine_t中保存了在当前nginx.conf配置下,一个用户请求可能经历的所有ngx_http_handler_pt处理方法,这是所有HTTP模块可以合作处理用户请求的关键,这个ngx_http_phase_engine_t结构体保存在全局的ngx_http_core_main_conf_t结构体中,如下:

在ngx_http_phase_t中关于HTTP阶段有两个成员:phase_engine和phases,其中phase_engine控制运行过程中的一个HTTP请求所要经过的HTTP处理阶段,它将配合ngx_http_request_t结构体中的phase_handler成员使用(phase_handler制定了当前请求应当执行哪一个HTTP阶段);而phases数组更像一个临时变量,它实际上仅会在Nginx启动过程中用到,它的唯一使命是按照11个阶段的概率初始化phase_engine中的handlers数组。

在HTTP框架的初始化过程中,任何HTTP模块都可以在ngx_http_module_t接口的postconfiguration方法中将自定义的方法添加到handler动态数组中,这样,这个方法就会最终添加到phase_engine动态数组中。

二、nginx lua 8个阶段

1)init_by_lua:

在nginx重新加载配置文件时,运行里面lua脚本,常用于全局变量的申请。(例如:lua_shared_dict共享内存的申请,只有当nginx重起后,共享内存数据才清空,这常用于统计。)

2)set_by_lua:

流程分支处理判断变量初始化(设置一个变量,常用与计算一个逻辑,然后返回结果,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API)

3)rewrite_by_lua:

转发、重定向、缓存等功能 (例如特定请求代理到外网,在access阶段前运行,主要用于rewrite)

4)access_by_lua:

IP准入、接口权限等情况集中处理(例如配合iptable完成简单防火墙,主要用于访问控制,能收集到大部分变量,类似status需要在log阶段才有。这条指令运行于nginx access阶段的末尾,因此总是在 allow 和 deny 这样的指令之后运行,虽然它们同属 access 阶段。)

5)content_by_lua:

内容生成,阶段是所有请求处理阶段中最为重要的一个,运行在这个阶段的配置指令一般都肩负着生成内容(content)并输出HTTP响应。

6)header_filter_by_lua:

应答HTTP过滤处理,一般只用于设置Cookie和Headers等,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API(例如添加头部信息)。

7)body_filter_by_lua:

应答BODY过滤处理(例如完成应答内容统一成大写)(一般会在一次请求中被调用多次, 因为这是实现基于 HTTP 1.1 chunked 编码的所谓“流式输出”的,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API)

8)log_by_lua:

会话完成后本地异步完成日志记录(日志可以记录在本地,还可以同步到其他机器)(该阶段总是运行在请求结束的时候,用于请求的后续操作,如在共享内存中进行统计数据,如果要高精确的数据统计,应该使用body_filter_by_lua,该阶段不能运行Output API、Control API、Subrequest API、Cosocket API)

三、nginx和lua运行阶段的对应关系

1)init_by_lua,运行在initialization Phase;

2)set_by_lua,运行在rewrite 阶段;

set 指令来自 ngx_rewrite 模块,运行于 rewrite 阶段;

3)rewrite_by_lua 指令来自 ngx_lua 模块,运行于 rewrite 阶段的末尾

4)access_by_lua 指令同样来自 ngx_lua 模块,运行于 access 阶段的末尾;

deny 指令来自 ngx_access 模块,运行于 access 阶段;

5)content_by_lua 指令来自 ngx_lua 模块,运行于 content 阶段;不要将它和其它的内容处理指令在同一个location内使用如proxy_pass;

echo 指令则来自 ngx_echo 模块,运行在 content 阶段;

6)header_filter_by_lua 运行于 content 阶段,output-header-filter 一般用来设置cookie和headers;

7)body_filter_by_lua,运行于 content 阶段;

8)log_by_lua,运行在Log Phase 阶段;

如图:


会员登录

会员登录

登录免费下载全站资源

获取验证码
登录
登录
开发简历

开发简历

简历模板网站自取

入坑需谨慎

入坑需谨慎

高薪完全靠自己

微信赞助-Java帮帮社区

微信赞助-Java帮帮社区

非盈利性学习社区

支付宝赞助-Java帮帮社区

支付宝赞助-Java帮帮社区

将分享做到极致

大公司资讯
文章附图

近日,在美国推出满一年的Facebook视频服务Watch,宣布正式向全球推广,这预示着视频领域中,YouTube...

文章附图

据彭博社北京时间9月19日报道,科技行业最引人注目的法律大战可能正在进入尾声。据高通CEO史蒂夫·莫伦科夫(Ste...

Java帮帮公众号生态

Java帮帮公众号生态

总有一款适合你

Java帮帮-微信公众号

Java帮帮-微信公众号

将分享做到极致

Python帮帮-公众号

Python帮帮-公众号

人工智能,爬虫,学习教程

大数据驿站-微信公众号

大数据驿站-微信公众号

一起在数据中成长

九点编程-公众号

九点编程-公众号

深夜九点学编程

程序员服务区-公众号

程序员服务区-公众号

吃喝玩乐,听学吐画

Java帮帮学习群生态

Java帮帮学习群生态

总有一款能帮到你

Java学习群

Java学习群

与大牛一起交流

大数据学习群

大数据学习群

在数据中成长

九点编程学习群

九点编程学习群

深夜九点学编程

python学习群

python学习群

人工智能,爬虫

测试学习群

测试学习群

感受测试的魅力

Java帮帮生态承诺

Java帮帮生态承诺

一直坚守,不负重望

初心
勤俭
诚信
正义
分享
合作品牌 非盈利生态-优质内容分享传播者
关于我们
友链申请
友链交换:加帮主QQ2524138991 留言即可 24小时内答复  
全站内容非商业用途,内容来源于网友,并遵循 CC BY-NC 4.0 许可,如有异议请联系客服。
会员登录
获取验证码
登录
登录
我的资料
留言
回到顶部