前言
Nginx作为一个http服务器,核心任务就是处理HTTP请求。在接收到请求时,Nginx框架首先解析http请求,将解析结果放在ngx_http_request中,由于http是在tcp上工作的,因此解析可能会持续一段时间。nginx用状态机完成对HTTP请求的异步解析。整个解析过程都是由Nginx框架代码完成,不需要用户介入。当解析得到完整的http请求后,就开始处理http请求。nginx对http请求的处理是分阶段进行的。对请求的处理也是用户主要介入nginx的地方。对于一个http请求,nginx主要分以下11个阶段进行处理:
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;
这篇博文将简单介绍一下这些处理请求时,这些阶段是怎么介入进去的。
http请求的处理 – ngx_http_handler
http请求处理的入口是ngx_http_process_request函数:
void
ngx_http_process_request(ngx_http_request_t *r)
在ngx_http_process_request函数中,我们可以看到:
c->read->handler = ngx_http_request_handler;
c->write->handler = ngx_http_request_handler;
r->read_event_handler = ngx_http_block_reading;
ngx_http_handler(r);
也就是说,下次有读写事件在这个连接上发生时,将会调用ngx_http_request_handler处理函数。
static void
ngx_http_request_handler(ngx_event_t *ev)
{
ngx_connection_t *c;
ngx_http_request_t *r;
ngx_http_log_ctx_t *ctx;
c = ev->data;
r = c->data;
ctx = c->log->data;
ctx->current_request = r;
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http run request: \"%V?%V\"", &r->uri, &r->args);
if (ev->write) {
r->write_event_handler(r); //ngx_http_core_run_phases
} else {
r->read_event_handler(r);
}
ngx_http_run_posted_requests(c);
}
我们可以看到这个函数主要是通过调用r->read_event_handler和r->write_event_handler来完成任务。
而从ngx_http_process_request里面可以看到:
r->read_event_handler = ngx_http_block_reading;
r->write_event_handler在ngx_http_handler函数中被设置:
r->write_event_handler = ngx_http_core_run_phases;
由于处理http请求主要是处理写事件,因为