在使用subrequest時,須要瞭解下面3個場景:nginx
- 啓動subrequest後子請求時如何運行的;
- 子請求如何存放收到的響應;
- 子請求結束時如何回調處理方法,以及激活父請求的處理方法。
一,如何啓動subrequest
處理父請求的過程當中會建立子請求,在父請求處理方法返回NGX_DONE後,HTTP框架會執行子請求,下面將介紹subrequest啓動過程: 服務器
(1)NGX主循環會按期地調用事件模塊,檢查是否有網絡事件發生;網絡
(2)事件模塊發現這個請求的回調方法屬於HTTP框架,交由HTTP框架來處理;框架
(3)根據解析完的URI來決定使用哪一個location下的模塊來處理這個請求;異步
(4)調用mytest模塊的ngx_http_mytest_handler方法處理這個請求;post
(5)設置subrequest子請求的URI及回調方法;//5-9步請見subrequest使用方式一節介紹spa
(6)調用ngx_http_subrequest方法建立子請求;代理
(7)建立的子請求會添加到原始請求的posted_requests鏈表中;blog
(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, 流程以下:
(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主循環。