Nginx的请求处理流程之一:分派handler

Nginx的请求处理流程之一:分派handler

一、nginx的http请求和响应流程

上图的handlers就是自己实现的一般的module中的handler,是根据conf中的如location的设置来选取调用哪个module。filers则是nginx的过滤器module,对生成的响应内容做辅助的修改,filters模块链表的最后一个模块是 ngx_http_write_filter_module,其函数 ngx_http_write_filter()调用send_chain()发送处理完毕的数据。
本文仅解析从接收完毕请求后,执行handlers,到调用filters之前,nginx的工作流程。
至于handler中的调用和发送流程,另外文章《Nginx的请求处理流程之二:handler发送包头、包体》中的详细说明。

二、nginx的请求响应过程的函数调用
这部分调用流程如图:

1、ngx_http_process_request()
开始处理请求,初始化请求读写事件的各handler回调函数:

void ngx_http_process_request(ngx_http_request_t *r)
{
...
c->read->handler = ngx_http_request_handler; //在 一次接收请求处理的流程中 ,连接的读写事件的handler是固定的。
c->write->handler = ngx_http_request_handler;
r->read_event_handler = ngx_http_block_reading ; //因为已经读完了,不再读了。

ngx_http_handler(r); //跳到ngx_http_core_module
ngx_http_run_posted_requests(c); //响应post请求
}
其中的几个函数主要流程如下:

void ngx_http_handler(ngx_http_request_t *r)
{
...
r->write_event_handler = ngx_http_core_run_phases; //设置为阶段处理函数
ngx_http_core_run_phases(r);
}

void ngx_http_request_handler (ngx_event_t *ev)
{
...
if (ev->write) {
r->write_event_handler(r);
} else {
r->read_event_handler(r);
}

ngx_http_run_posted_requests(c);
}

void ngx_http_run_posted_requests(ngx_connection_t *c)
{
ngx_http_request_t *r;
ngx_http_posted_request_t *pr;

for ( ;; ) {
if (c->destroyed) return;

r = c->data;
pr = r->main->posted_requests;
if (pr == NULL) return;

r->main->posted_requests = pr->next; // post请求链表
r = pr->request;

r->write_event_handler(r);
}
}

小结:
ngx_http_handler()是ngx_http_core_module模块的,该模块负责各http类模块的调度。此函数主要是初始化了请求的写事件handler为 ngx_http_core_run_phases
至此,请求的读写事件的handler才都初始化完成了。而connect的读写事件的handler都指向这个函数 ngx_http_request_handler()
  • 如果是写事件,则执行r->write_event_handler,是ngx_http_core_run_phases
  • 如果是读事件,则执行r->read_event_handler,是ngx_http_block_reading
write_event_handler、write_event_handler的类型是void的函数指针:typedef void (*ngx_http_event_handler_pt)(ngx_http_request_t *r);
注意:
  • ngx_http_request_handler()是优先执行写事件的。

2、ngx_http_core_run_phases()
调度执行各阶段的http模块的handler。
也是ngx_http_core_module模块的,遍历http阶段以分别调用不同的checker函数。而各http模块的handler,就是在对应的checker函数中被调用的。

void ngx_http_core_run_phases(ngx_http_request_t *r)
{
ngx_int_t rc;
ngx_http_phase_handler_t *ph;
ngx_http_core_main_conf_t *cmcf;

cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
ph = cmcf->phase_engine.handlers;

while (ph[ r->phase_handler ].checker) { //当前阶段
rc = ph[r->phase_handler]. checker (r, &ph[r->phase_handler]); // 执行checker
if (rc == NGX_OK) return; //checker返回值为NGX_OK时,退出while循环。
}
}

//NGX_HTTP_CONTENT_PHASE阶段的checker方法:
ngx_int_t ngx_http_core_content_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
{
...
rc = ph->handler(r);
if (rc != NGX_DECLINED) {
ngx_http_finalize_request(r, rc);
return NGX_OK;
}

ph++; // 当前phase的数组的下一个元素,不是下一阶段
if (ph->checker) {
r->phase_handler++; //本阶段的下一个check存在,则序号加1;否则结束
return NGX_AGAIN;
}

...
ngx_http_finalize_request(r, NGX_HTTP_NOT_FOUND);
return NGX_OK;
}
这里被执行handler的 HTTP模块,都是本次请求的URI匹配了nginx.conf中某个server或location表达式下的变量名的。
这里执行content类型的HTTP模块中的handler,并根据其返回值进行http框架流程中的后续分派处理。对于模块来说,这里是唯一的入口,一般在此handler函数中处理请求内容,完毕后调用ngx_http_output_filter()发回应答。
如果handler的返回值是NGX_DECLINED的话,才继续下一个?。
注意本函数返回值:
  • 要么返回NGX_OK,结束本次请求,并归还事件控制权。
  • 要么返回NGX_AGAIN,指向下一个r->phase_handler继续执行。

总结:
当所有checker执行完毕,或者有checker返回NGX_OK时,退出ngx_http_core_run_phases()的执行循环。也就是本次的处理请求的工作就执行完毕了。
注意其中checker执行完会执行 ngx_http_finalize_request(),也就是说如果不满足一次执行完毕时,会在这个函数中触发异步执行的——即重新设置请求的读写事件的handler,再次将写事件放入事件处理。但是这个异步执行将仅限于特殊结果和需要延迟的发送(详见下节)。

3、void ngx_http_finalize_request()
这里根据http模块的handler返回结果进行重新分派:
  • NGX_DONE,正常结束。则ngx_http_finalize_connection()关闭连接,返回。
  • NGX_DECLINED,从头再来。则走ngx_http_core_run_phases(),重新开始,返回。(其他流程调用到这里的,而不是ngx_http_core_content_phase)
  • NGX_ERROR等,强制结束。则ngx_http_terminate_request()终止请求,返回。
  • NGX_HTTP_SPECIAL_RESPONSE等特殊结果,ngx_http_special_response_handler()组特殊ack发送,返回。
  • 其他如NGX_AGAIN,NGX_BUSY没有明确标出,但如果是(r->buffered || c->buffered || r->postponed || r->blocked),则执行ngx_http_set_write_handler(),返回。
  • 以上皆不是,则设置 r->write_event_handler=gx_http_request_empty_handler;再关闭连接,返回。

注:
1、ngx_http_set_write_handler()及其之后的解析,请看下文分解。
2、rc返回值定义:
#define NGX_OK 0
#define NGX_ERROR -1
#define NGX_AGAIN -2
#define NGX_BUSY -3
#define NGX_DONE -4
#define NGX_DECLINED -5
#define NGX_ABORT -6

#define NGX_HTTP_SPECIAL_RESPONSE 300


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值