nginx对http请求处理的各个阶段详析

在编写nginx的http的模块的时候,需要在各个阶段对http请求做相应的处理,以达到不同的目的,比如请求发起的时候是否有访问权限、内容生成的时候进行过滤或者其它处理等等。如果在编译nginx模块内注册的处理阶段不正确会导致达不到想要的结果,比如你想处理内容的时候内容实际上这个时候是没有的,如此等等。

在nginx内部定义了多个阶段的类型以满足不同的处理要求(ngx_http_core_module.h中,不同版本不一样):

typedef enum {
 NGX_HTTP_POST_READ_PHASE = 0,

 NGX_HTTP_SERVER_REWRITE_PHASE,

 NGX_HTTP_FIND_CONFIG_PHASE,
 NGX_HTTP_REWRITE_PHASE,
 NGX_HTTP_POST_REWRITE_PHASE,

 NGX_HTTP_PREACCESS_PHASE,

 NGX_HTTP_ACCESS_PHASE,
 NGX_HTTP_POST_ACCESS_PHASE,

 NGX_HTTP_TRY_FILES_PHASE,
 NGX_HTTP_CONTENT_PHASE,

 NGX_HTTP_LOG_PHASE
} ngx_http_phases;

各对应的意思分别为:

NGX_HTTP_POST_READ_PHASE = 0  //读取请求阶段
NGX_HTTP_SERVER_REWRITE_PHASE //URI转换阶段
NGX_HTTP_FIND_CONFIG_PHASE   //查找相应的配置来执行阶段
NGX_HTTP_REWRITE_PHASE    //URI转换阶段(不太清楚此处)
NGX_HTTP_POST_REWRITE_PHASE  //对转换后的URL结果进行处理的阶段
NGX_HTTP_PREACCESS_PHASE   //权限检查准备阶段
NGX_HTTP_ACCESS_PHASE    //权限检查阶段
NGX_HTTP_POST_ACCESS_PHASE  //对权限检查结果进行处理阶段
NGX_HTTP_TRY_FILES_PHASE   //处理配置中的try_files阶段
NGX_HTTP_CONTENT_PHASE    //处理生成返回数据阶段(此处认为不太细,当然有filter也可以忽略)
NGX_HTTP_LOG_PHASE     //记录日志处理阶段,具体说明应当是请求完成后,关闭请求时处理

从这个配置中可以分析出来nginx在处理请求的整个流程,流程是从头执行到尾的,可见LOG是放在最后面执行,对于内容段的处理一般都是在filter模块中去做,在NGX_HTTP_LOG_PHASE阶段注册的处理段也不能获取到返回的数据,返回数据在发送至客户端后就直接给释放了。因此,在各个阶段处理时应当清楚这个阶段的数据准备情况。

正常情况下,我们可以通过如下的方式来注册我们自己的处理模块:

static ngx_int_t
ngx_http_xxx_init(ngx_conf_t *cf)
{
 ngx_http_handler_pt  *h;
 ngx_http_core_main_conf_t *cmcf;

 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);

 h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
 if (h == NULL) {
 return NGX_ERROR;
 }

 *h = ngx_http_xxx_handler;

 return NGX_OK;
}

且ngx_http_xxx_up_handler的返回值只能是如下几个:

NGX_OK        //处理成功,进入下一阶段
NGX_DECLINED      //放弃处理
NGX_AGAIN || NGX_DONE  //处理完成,返回该值会触发请求
NGX_ERROR || NGX_HTTP_.. //处理错误或者HTTP的其它状态值

另外对于NGX_HTTP_CONTENT_PHASE阶段,实际上还有另外一种注册方式,Just like this:

static char *
ngx_http_xxx_server(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
 ngx_str_t     *value;
 ngx_url_t     u;
 ngx_http_core_loc_conf_t *clcf;

 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);

 clcf->handler = ngx_http_xxx_handler;

 if (clcf->name.data[clcf->name.len - 1] == '/') {
 clcf->auto_redirect = 1;
 }

 return NGX_CONF_OK;
}

不过这样子,你要做的东西就太多了,更多的情况下考虑下upstream结合或者对请求进行特殊处理,比如对于分布式存储的分发,需要对请求处理和文件系统关联时、比如请求的数据直接交给特殊的SERVER来拿内容时。呵呵.

到此这篇关于nginx对http请求处理的各个阶段详析的文章就介绍到这了,更多相关nginx对http请求处理详析内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • nginx处理http请求实例详解

    本文在这基础上分析nginx服务器收到http请求行.请求头部后,http框架是如何调度各个http模块共同完成这个http请求.例如: http框架调度静态模块,获取服务器目录下的某个html页面返回给客户端: 或者http框架调度access权限访问模块,判断这个客户端是否有权限访问服务器. 一.event事件与http框架的交互 在接收完http请求行.http请求头部后,会调用ngx_http_process_request这个函数开始处理http请求.因为一个http请求由11个处理阶

  • Linux服务器nginx访问日志里出现大量http 400错误的请求分析

    服务器中的错误记录类似于这种: 124.65.133.242 – – [27/Oct/2014:14:30:51 +0800] "-" 400 0 "-" "-" 124.65.133.242 – – [27/Oct/2014:14:31:45 +0800] "-" 400 0 "-" "-" 124.65.133.242 – – [27/Oct/2014:14:31:45 +0800]

  • 详解Nginx http资源请求限制(三种方法)

    前置条件:nginx 需要有 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模块,可以使用命令 2>&1 nginx -V | tr ' ' '\n'|grep limit 检查有没有相应模块,如果没有请重新编译安装这两个模块. 测试版本为:nginx版本为1.15+ 限制链接数 1.使用 limit_conn_zone 指令定义密钥并设置共享内存区域的参数(工作进程将使用此区域来共享密钥值的计数器).第一个参数指定作为键计算的

  • nginx对http请求处理的各个阶段详析

    在编写nginx的http的模块的时候,需要在各个阶段对http请求做相应的处理,以达到不同的目的,比如请求发起的时候是否有访问权限.内容生成的时候进行过滤或者其它处理等等.如果在编译nginx模块内注册的处理阶段不正确会导致达不到想要的结果,比如你想处理内容的时候内容实际上这个时候是没有的,如此等等. 在nginx内部定义了多个阶段的类型以满足不同的处理要求(ngx_http_core_module.h中,不同版本不一样): typedef enum { NGX_HTTP_POST_READ_

  • Nginx内容缓存以及常见参数配置详析

    使用场景: 项目的页面需要加载很多数据,也不是经常变化的,不涉及个性化定制,为每次请求去动态生成数据,性能比不上根据请求路由和参数缓存一下结果,使用 Nginx 缓存将大幅度提升请求速度. 基础 只需要配置 proxy_cache_path 和 proxy_cache 就可以开启内容缓存,前者用来设置缓存的路径和配置,后者用来启用缓存. http { ... proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max

  • Nginx处理请求时的匹配规则详析

    nginx 在收到一条请求时将先通过 server_name 匹配一个 server, 然后使用 server 中的 location 继续匹配. 匹配 server_name 在 nginx 中, server_name 决定了当收到一个请求后哪一个 server 会被使用. nginx 会使用请求头中的 Host 字段与 server_name 进行匹配. 定义 server_name 时可以使用 完全名称.通配符名称.正则表达式名称, 它们的匹配顺序如下: 完全匹配 前通配符匹配, 即 *

  • Nginx中break与last的区别详析

    先说区别 last,重写后的规则,会继续用重写后的值去匹配下面的location. break,重写后的规则,不会去匹配下面的location.使用新的规则,直接发起一次http请求了. Nginx 配置文件 server { listen 88; server_name _; location /break { # location 1 rewrite ^/break/(.*)$ /bak/$1 break; } location /last { # location 2 rewrite ^/

  • nginx pod hook钩子优雅关闭示例详解

    目录 一.系统环境 二.前言 三.pod hook(pod钩子) 四.如何优雅的关闭nginx pod 一.系统环境 服务器版本 docker软件版本 Kubernetes(k8s)集群版本 CPU架构 CentOS Linux release 7.4.1708 (Core) Docker version 20.10.12 v1.21.9 x86_64 Kubernetes集群架构:k8scloude1作为master节点,k8scloude2,k8scloude3作为worker节点 服务器

  • Nginx丢弃http包体处理实例详解

    Nginx丢弃http包体处理实例详解 http框架丢弃http请求包体和上一篇文章http框架接收包体, 都是由http框架提供的两个方法,供http各个模块调用,从而决定对包体做什么处理.是选择丢弃还是接收,都是由模块决定的.例如静态资源模块,如果接收到来自浏览器的get请求,请求某个文件时,则直接返回这个文件内容给浏览器就可以了.没有必要再接收包体数据,get请求实际上也不会有包体.因此静态资源模块将调用http框架提供的丢弃包体函数进行丢包处理. 相比接收包体过程, 丢弃包体操作就简单很

  • 找出nginx配置文件的所在位置的方法详解

    对于一台陌生的服务器或安装太久忘了位置,怎么才能简单快速的找到配置文件的位置呢?要找出配置文件的位置,需要先找出nginx可执行文件的路径 , 这里有几种方法: 1.如果程序在运行中 ps -ef | grep nginx # ps -ef | grep nginx root 29514... 对于一台陌生的服务器或安装太久忘了位置,怎么才能简单快速的找到配置文件的位置呢? 要找出配置文件的位置,需要先找出nginx可执行文件的路径 , 这里有几种方法: 1.如果程序在运行中 ps -ef |

  • nginx常用命令放入shell脚本详解

    1.创建一个文件夹存放nginx的shell脚本 /usr/local/task/nginx 1)重启nginx的shell脚本 vim reload.sh #!/bin/bash nginx -s reload 2)设置nginx用户对html目录下所有文件读写执行权限的shell脚本 vim setfacl.sh #!/bin/bash setfacl -m u:nginx:rwx -R /usr/local/nginx/html/ setfacl -m d:u:nginx:rwx -R /

  • nginx服务器的下载安装与使用详解

    下载 http://nginx.org/en/download.html 解压 将下载后的 nginx-1.19.8.zip 压缩包解压缩到 D:/applications 目录下. 解压后的目录结构如下: <img src="images\nginx-directory.png" style="zoom:80%;border:1px solid gray;" /> 配置 在 conf 目录中找到 nginx.conf 文件,先备份后再修改该文件. 修改

  • 关于指令重排现象的两个阶段详解

    目录 编译期指令重排 1.上神秘代码 2.编译成Java字节码(没加volatile) 3.编译成Java字节码(加了volatile) 4.编译器优化 运行期指令重排 那什么时候会产生指令重排现象呢?两个阶段:1.编译期:2.运行期. 编译期指令重排 解释型语言是在运行期间执行编译+运行动作,所以运行效率较编译型语言低.Java既可以作为解释型语言去用,也可以作为编译型语言.但是主流的做法是当成编译型语言在用.那Java在编译期做了指令重排优化吗?做了哪些优化?能不能让我看看?为了满足大家的好

随机推荐