NGINX中HTTP请求的11个处理阶段
来源:互联网 发布:广告设计用什么软件 编辑:程序博客网 时间:2024/05/21 15:04
Nginx的模块化设计使得每一个HTTP模块可以仅专注于完成一个独立的、简单的功能,而一个请求的完整处理过程可以由无数个HTTP模块共同合作完成。这种设计有非常好的简单性、可测试性、可扩展性,然而,当多个http模块流水式地处理同一个请求时,单一的处理顺序是无法满足灵活性需求的,每一个正在处理的HTTP模块很难灵活、有效地指定下一个HTTP处理模块是哪一个。
因此,HTTP框架依据常见的处理流程将处理阶段划分为11个阶段,其中每个处理阶段都可以由任意多个HTTP模块流水式地处理请求。
typedef enum { //在接收到完整的HTTP头部后处理的HTTP阶段 NGX_HTTP_POST_READ_PHASE = 0, //在请求的URI与location表达式匹配前,修改请求的URI(重定向),是一个独立的HTTP阶段 NGX_HTTP_SERVER_REWRITE_PHASE, //根据请求的URI寻找匹配的location表达式,这个阶段只能由 NGX_HTTP_FIND_CONFIG_PHASE, //在NGX_HTTP_FIND_CONFIG_PHASE阶段寻找到匹配的location之后再修改请求的URI NGX_HTTP_REWRITE_PHASE, //这一阶段是用于在rewrite重写URL后,防止错误的nginx.conf配置导致死循环(递归地修改URI) NGX_HTTP_POST_REWRITE_PHASE, //表示在处理NGX_HTTP_ACCESS_PHASE阶段觉得请求的访问权限前,HTTP模块可以介入的处理阶段 NGX_HTTP_PREACCESS_PHASE, //这个阶段用于让HTTP模块判断是否允许这个请求访问nginx服务器 NGX_HTTP_ACCESS_PHASE, //在NGX_HTTP_ACCESS_PHASE阶段中,当HTTP模块的handler处理函数返回不允许访问的错误码时(NGX_HTTP_FORBIDDEN或者NGX_HTTP_UNAUHORIZED),这里将负责向用户发送拒绝服务的错误响应。 NGX_HTTP_POST_ACCESS_PHASE, //此阶段专门为try_files配置项设立,当HTTP请求访问静态文件资源时,try_files配置项可以使这个配置项顺序地访问多个静态文件资源 NGX_HTTP_TRY_FILES_PHASE, //用于处理HTTP请求内容的阶段,这是大部分HTTP模块最愿意介入的阶段 NGX_HTTP_CONTENT_PHASE, //处理完请求后记录日志的阶段,ngx_http_log_module模块就在这个阶段中加入了一个handler处理方法,使得每个HTTP请求处理完毕后会记录access_log访问日志 NGX_HTTP_LOG_PHASE} ngx_http_phases;
这11个阶段有些是必备的,有些是可选的,也可以有多个HTTP模块同时介入同一阶段
HTTP阶段的定义,包括checker检查方法和handler处理方法,如下所示:
typedef structngx_http_phase_handler_s ngx_http_phase_handler_t; /*一个HTTP处理阶段中的checker检查方法,仅可以由HTTP框架实现,以此控制HTTP请求的处理流程*/typedef ngx_int_t(*ngx_http_phase_handler_pt)(ngx_http_request_t *r, ngx_http_phase_handler_t*ph);/*由HTTP模块实现的handler处理方法*/typedef ngx_int_t(*ngx_http_handler_pt)(ngx_http_request_t *r);struct ngx_http_phase_handler_s {/*在处理到某一个HTTP阶段时,HTTP框架将会在checker方法已实现的前提下首先调用checker方法来处理请求,而不会直接调用任何阶段中的hanlder方法,只有在checker方法中才会去调用handler方法,因此,事实上所有的checker方法都是由框架中的ngx_http_core_module模块实现的,且普通模块无法重定义checker方法*/ngx_http_phase_handler_pt checker; /*除ngx_http_core_module模块以外的HTTP模块,只能通过定义handler方法才能介入某一个HTTP处理阶段以处理请求*/ngx_http_handler_pt handler; /*将要处理的下一个HTTP处理阶段的序号next的设计使得处理阶段不必按顺序依次执行,既可以向后跳跃数个阶段继续执行,也可以跳跃到之前的某个阶段重新执行,通常,next表示下一个处理阶段中的第1个ngx_http_phase_handler_t处理方法*/ngx_uint_t next;};
一个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组成的数组,如下所示:
typedef struct {/*handlers是由ngx_http_phase_handler_t构成的数组首地址,它表示一个请求可能经历的所有ngx_http_handler_pt处理方法*/ngx_http_phase_handler_t *handlers; /*表示NGX_HTTP_SERVER_REWRITE_PHASE阶段第1个ngx_http_phase_handler_t处理方法在handlers数组中的序号,用于在执行HTTP请求的任何阶段中快速跳转到HTTP_SERVER_REWRITE_PHASE阶段处理请求*/ngx_uint_t server_rewrite_index; /*表示NGX_HTTP_PREACCESS_PHASE阶段第1个ngx_http_phase_handler_t处理方法在handlers数组中的序号,用于在执行HTTP请求的任何阶段中快速跳转到NGX_HTTP_PREACCESS_PHASE阶段处理请求*/ngx_uint_t location_rewrite_index;} ngx_http_phase_engine_t;
可以看到,ngx_http_phase_engine_t中保存了在当前nginx.conf配置下,一个用户请求可能经历的所有ngx_http_handler_pt处理方法,这是所有HTTP模块可以合作处理用户请求的关键,这个ngx_http_phase_engine_t结构体保存在全局的ngx_http_core_main_conf_t结构体中,如下:
typedef struct {ngx_array_t servers; /* ngx_http_core_srv_conf_t *//*由下面各阶段处理方法构成的phases数组构建的阶段引擎才是流水式处理HTTP请求的实际数据结构*/ngx_http_phase_engine_t phase_engine;ngx_hash_t headers_in_hash;ngx_hash_t variables_hash;ngx_array_t variables; /* ngx_http_variable_t */ngx_uint_t ncaptures;ngx_uint_t server_names_hash_max_size;ngx_uint_t server_names_hash_bucket_size;ngx_uint_t variables_hash_max_size;ngx_uint_t variables_hash_bucket_size;ngx_hash_keys_arrays_t *variables_keys;ngx_array_t *ports;ngx_uint_t try_files; /* unsigned try_files:1 *//*用于在HTTP框架初始化时帮助各个HTTP模块在任意阶段中添加HTTP处理方法,它是一个有11个成员的ngx_http_phase_t数组,其中每一个ngx_http_phase_t结构体对应一个HTTP阶段,在HTTP框架初始化完毕后,运行过程中的phases数组是无用的*/ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1];} 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数组
typedef struct {/*handlers动态数组保存着每一个HTTP模块初始化时添加到当前阶段的处理方法*/ngx_array_t handlers;} ngx_http_phase_t;
参考:《深入理解Nginx模块开发与架构设计》 陶辉 机械工业出版社
- NGINX中HTTP请求的11个处理阶段
- 【Nginx】HTTP请求的11个处理阶段
- 《深入理解Nginx》笔记之 HTTP请求的11个处理阶段
- Nginx多阶段处理HTTP请求
- Nginx中http请求的处理过程
- Nginx 中处理 HTTP 请求
- nginx的多阶段请求处理
- nginx的多阶段请求处理
- 文章13:Nginx多阶段处理HTTP请求
- Nginx的HTTP请求处理
- nginx的十一个阶段处理
- 文章18 :Nginx中http请求的处理过程
- Nginx源码剖析--HTTP请求各阶段的具体作用
- nginx 11个处理阶段 && nginx lua 8个处理阶段
- nginx处理http请求
- nginx 处理请求原理和每个阶段的意思
- Nginx处理HTTP请求的路由过程
- Nginx 11个阶段
- 一些linux面试题3.0
- Find命令的35个举例
- java创建多线程使用Executors创造ExecutorService
- 【NOIP2016提高A组集训第4场11.1】平衡的子集
- 4845. 【NOIP2016提高A组集训第5场11.2】寻找
- NGINX中HTTP请求的11个处理阶段
- 今天正式开通技术博客
- 如何使用smarty模板殷勤
- linux内核启动过程
- Unity 鼠标双击事件检测
- 你真的理解AccessibilityService吗
- 冒泡排序优化
- collectionview 集合视图流式布局
- linux 打包和压缩的概念和区别