深入理解NGINX-子请求:(5)subrequest执行过程中的主要场景

  在使用subrequest时,需要了解下面3个场景:

  1. 启动subrequest后子请求时如何运行的;
  2. 子请求如何存放收到的响应;
  3. 子请求结束时如何回调处理方法,以及激活父请求的处理方法。

一,如何启动subrequest

 处理父请求的过程中会创建子请求,在父请求处理方法返回NGX_DONE后,HTTP框架会执行子请求,下面将介绍subrequest启动过程: 

        深入理解NGINX-子请求:(5)subrequest执行过程中的主要场景

 

(1)NGX主循环会定期地调用事件模块,检查是否有网络事件发生;

(2)事件模块发现这个请求的回调方法属于HTTP框架,交由HTTP框架来处理;

(3)根据解析完的URI来决定使用哪个location下的模块来处理这个请求;

(4)调用mytest模块的ngx_http_mytest_handler方法处理这个请求;

(5)设置subrequest子请求的URI及回调方法;//5-9步请见subrequest使用方式一节介绍

(6)调用ngx_http_subrequest方法创建子请求;

(7)创建的子请求会添加到原始请求的posted_requests链表中;

(8)ngx_http_subrequest方法执行完毕,子请求创建成功;

(9)ngx_http_mytest_handler方法执行完毕,返回NGX_DONE,这样父请求不会被销毁,等待以后的再次激活;

(10)HTTP框架执行完当前请求(父请求)后,检查posted_requests链表中是否还有子请求,如果存在子请求,则调用子请求的write_event_handler方法;

(11)根据子请求的URI,检查nginx.conf所有的location配置,确定应有哪个模块执行子请求,比如可以用反向代理模块执行;

(12)调用模块入口方法来处理子请求,例如反向代理模块入口方法ngx_http_proxy_handler;

(13)由于反向代理模块使用了upstream机制,所以它也要通过很多次的异步调用才能完整的处理完子请求,这是它的入口方法返回的是NGX_DONE;

(14)再次检查是否还有子请求,这是已经发现没有子请求了,当然子请求可以继续创建新的子请求,只是这里的反向代理模块不会这样做;

(15)第二步中网络事件处理完毕后,将控制权交给事件模块;

(16)本轮网络事件处理完毕后,交还控制权给NGINX主循环。

 二,子请求如何激活父请求

  子请求在结束前会回调在ngx_http_post_subrequest_t中实现的handler方法,在这个handler方法中,又设置了父请求被激活后的执行方法,mytest_post_handler, 流程如下:

        深入理解NGINX-子请求:(5)subrequest执行过程中的主要场景

(1)nginx主循环定期地调用事件模块,检查是否有网络事件发生;

(2)如果事件模块监测到连接关闭事件,而这个请求的处理方法属于upstream模块,则交由upstream模块来处理请求;

(3)upstream模块开始调用ngx_http_upstream_finalize_request方法来结束upstream机制下的请求;

(4)调用HTTP框架提供的ngx_http_finalize_request方法来结束子请求;

(5)ngx_http_finalize_request方法会检查当前的请求是否是子请求,如果是,则会回调post_suberquest成员中的handler方法,也就是会调用mytest_subrequest_post_handler方法;

(6)在实现的子请求回调方法中,解析子请求返回的响应包。注意,这时需要通过write_event_handler设置父请求被激活后的回调方法(因为此时父请求的回调方法已经被HTTP框架设置为什么事都不做的ngx_http_request_empty_handler方法);

(7)子请求的回调方法执行完毕后,交由HTTP框架的ngx_http_finalize_request方法继续向下执行;

(8)ngx_http_finalize_request方法执行完毕;

(9)HTTP框架如果发现当前请求后还有父请求需要执行,则调用父请求的write_event_handler回调方法;

(10)这里可以根据第6步中解析子请求响应后的结果来构造响应包;

(11)调用无阻塞的ngx_http_send_header、ngx_http_output_filter发送方法,向客户端发送响应包;

(12)无阻塞发送方法会立刻返回,即使目前未发送完,nginx之后也会异步地发送完所有的响应包,然后再结束请求;

(13)父请求的回调方法执行完毕;

(14)当第2步中的上游服务器连接关闭事件处理完毕后,交还控制权给事件模块;

(15)本轮网络事件处理完毕后,交还控制权给nginx主循环。

 

上一篇:Nginx stream模块初探


下一篇:angular6 页面加载数据时的loading提示