nginx源码分析--状态机模型

本文探讨了nginx如何通过11个处理阶段构建其状态机模型,重点关注ngx_http_phase_t数组在初始化过程中的作用,以及各阶段处理器的配置和执行。在http模块初始化时,例如NGX_HTTP_SERVER_REWRITE_PHASE和NGX_HTTP_REWRITE_PHASE,通过ngx_http_rewrite_handler等函数进行处理。最终,状态机的核心运行依赖于cmcf->phase_engine.handlers数组中的处理器轮转。
摘要由CSDN通过智能技术生成

nginx在处理客户端发来的http数据,主要是通过11个阶段的处理,形成了状态机模式。

typedef struct {
   
    ngx_array_t                servers;         /* ngx_http_core_srv_conf_t */
    //http框架初始化后各个http模块构造的处理方法组成phase_engine,由下面各阶段处理方法构成的phase数组构建的阶段引擎才是流水式处理http请求的实际数据结构
    ngx_http_phase_engine_t    phase_engine;

    //用于在http框架初始化时帮助各个http模块在任意阶段中添加http处理方法,它是一个有11个成员的ngx_http_phase_t数组,其中每一个ngx_http_phase_t结构体对应一个
    //http阶段。在http框架初始化完成后,运行过程中的phase数组是无用的。
    ngx_http_phase_t           phases[NGX_HTTP_LOG_PHASE + 1]; //http状态机,每个phases都是一个数组
} ngx_http_core_main_conf_t;

typedef struct {
   
    //handlers动态数组保存着每一个http模块初始化时添加到当前阶段的处理方法
    ngx_array_t                handlers;
} ngx_http_phase_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请求的任何阶段中快速跳转到NGX_HTTP_SERVER_REWRITE_PHASE阶段处理请求
    ngx_uint_t                 server_rewrite_index;
    //表示NGX_HTTP_REWRITE_PHASE阶段第1个ngx_http_phase_handler_t处理方法在handlers数组中的序号,用于在执行http请求
    //的任何阶段中快速跳转到NGX_HTTP_REWRITE_PHASE阶段处理请求
    ngx_uint_t                 location_rewrite_index;
} ngx_http_phase_engine_t;

struct ngx_http_phase_handler_s {
   
    //每个handler方法必须对应一个checker方法,这个checker方法由http框架实现
    ngx_http_phase_handler_pt  checker; //函数指针
    //各个http模块实现的方法
    ngx_http_handler_pt        handler; //函数指针
    ngx_uint_t                 next;
};

ngx_http_phase_t phases[NGX_HTTP_LOG_PHASE + 1]在初始化phase_engine的时候使用一次,使用完只有就没有作用了。
为phases开辟内存空间,每个cmcf->phases[?].handlers都是一个数组:

/**
 * 初始化阶段处理数组
 * 每一个可以挂载模块的阶段,都定义了一个cmcf->phases[?].handlers的数组
 * 每个阶段被调用的时候,都会去遍历改阶段处理数组下需要处理的逻辑函数
 */
static ngx_int_t
ngx_http_init_phases(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
{
   
    //申请指针数组,用于存储该阶段的处理函数指针
    if (ngx_array_init(&cmcf->phases[NGX_HTTP_POST_READ_PHASE].handlers,
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers,
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers,
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers,
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_ACCESS_PHASE].handlers,
                       cf->pool, 2, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_PRECONTENT_PHASE].handlers,
                       cf->pool, 2, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers,
                       cf->pool, 4, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    if (ngx_array_init(&cmcf->phases[NGX_HTTP_LOG_PHASE].handlers,
                       cf->pool, 1, sizeof(ngx_http_handler_pt))
        != NGX_OK)
    {
   
        return NGX_ERROR;
    }

    return NGX_OK;
}
阶段处理 对应函数 开辟内存 描述信息
NGX_HTTP_POST_READ_PHASE ngx_http_core_generic_phase 1 读取请求内容阶段,这个阶段没有默认的handler,主要用来读取请求体,并对请求体做相应的处理
NGX_HTTP_SERVER_REWRITE_PHASE ngx_http_core_rewrite_phase 1 Server请求地址重写阶段,这个阶段主要是处理全局的(server block)的rewrite规则
NGX_HTTP_FIND_CONFIG_PHASE ngx_http_core_find_config_phase 配置查找阶段,不支持ch,这个阶段主要是通过uri来查找对应的location。然后将uri和locatio
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值