日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

nginx phase handler的原理和选择

發(fā)布時間:2024/2/28 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 nginx phase handler的原理和选择 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

nginx phase handler的原理和選擇
PHASE HANDLER的種類
nginx在接收并解析完請求行,請求頭之后,就會依次調(diào)用各個phase handler。 phase handler是完成nginx主要功能的階段。

Nginx有如下11種phase,phase會依次執(zhí)行。同一個phase,可能會掛載多個handler。其中斜體加粗的phase,不允許掛載用戶自定義的handler

PHASE?? ?備注
NGX_HTTP_POST_READ_PHASE?? ?讀取請求內(nèi)容階段
NGX_HTTP_SERVER_REWRITE_PHASE?? ?Server請求地址重寫階段
NGX_HTTP_FIND_CONFIG_PHASE?? ?配置查找階段
NGX_HTTP_REWRITE_PHASE?? ?Location請求地址重寫階段
NGX_HTTP_POST_REWRITE_PHASE?? ?請求地址重寫提交階段
NGX_HTTP_PREACCESS_PHASE?? ?訪問權(quán)限檢查準(zhǔn)備階段
NGX_HTTP_ACCESS_PHASE?? ?訪問權(quán)限檢查階段
NGX_HTTP_POST_ACCESS_PHASE?? ?訪問權(quán)限檢查提交階段
NGX_HTTP_TRY_FILES_PHASE?? ?配置項try_files處理階段
NGX_HTTP_CONTENT_PHASE?? ?內(nèi)容產(chǎn)生階段
NGX_HTTP_LOG_PHASE?? ?日志模塊處理階段
如何注冊phase handler
一般情況下,我們自定義的模塊,大多數(shù)是掛載在NGX_HTTP_CONTENT_PHASE階段的。掛載的動作一般是在模塊上下文調(diào)用的postconfiguration函數(shù)中。

掛載的代碼示例如下:

static ngx_int_t
ngx_http_hello_init(ngx_conf_t *cf) ? ?// postconfiguration hook點
{
? ? ? ? ngx_http_handler_pt ? ? ? ?*h;
? ? ? ? ngx_http_core_main_conf_t ?*cmcf;
?
? ? ? ? cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);
?
? ? ? ? h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
? ? ? ? if (h == NULL) {
? ? ? ? ? ? ? ? return NGX_ERROR;
? ? ? ? }
?
? ? ? ? *h = ngx_http_hello_handler;
?
? ? ? ? return NGX_OK;
}

cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers 是content phase階段的handler數(shù)組,類似的:

cmcf->phases[NGX_HTTP_SERVER_REWRITE_PHASE].handlers?
cmcf->phases[NGX_HTTP_REWRITE_PHASE].handlers
cmcf->phases[NGX_HTTP_PREACCESS_PHASE].handlers
。。。
每個可掛載的phase,都有一個phase handler數(shù)組, 你可以選擇掛載在不同的phase數(shù)組里

Nginx在解析http的配置時,會將多個phase handler數(shù)組,合成為一個數(shù)組

static char *
ngx_http_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) ?// http指令的hook函數(shù)
{
? ? 。。。?
? ? for (m = 0; ngx_modules[m]; m++) {
? ? ? ? if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
? ? ? ? ? ? continue;
? ? ? ? }
?
? ? ? ? module = ngx_modules[m]->ctx;
?
? ? ? ? if (module->postconfiguration) {
? ? ? ? ? ? if (module->postconfiguration(cf) != NGX_OK) {// 執(zhí)行各模塊的postconfigure hook, phase handler就在此時掛載
? ? ? ? ? ? ? ? return NGX_CONF_ERROR;
? ? ? ? ? ? }
? ? ? ? }
  }
  。。。
  
  if (ngx_http_init_phase_handlers(cf, cmcf) != NGX_OK) {// 將多個phase handler數(shù)組,合成為一個數(shù)組
  ? ? return NGX_CONF_ERROR;
  }
? ?。。。
}
ngx_http_init_phase_handlers(cf, cmcf) 函數(shù)將(除log phase以外的)幾個phase handler數(shù)組,合成為一個ngx_http_phase_handler_t類型的數(shù)組

struct ngx_http_phase_handler_s {
? ? ngx_http_phase_handler_pt ?checker; // 檢查handler返回結(jié)果,決定下一個執(zhí)行的handler
? ? ngx_http_handler_pt ? ? ? ?handler; // handler 鉤子
? ? ngx_uint_t ? ? ? ? ? ? ? ? next; ? ?// 指向下一個phase的第一個handler
};
以下是不同的phase,對應(yīng)不同的checker函數(shù)

PHASE?? ?checker
NGX_HTTP_POST_READ_PHASE?? ?ngx_http_core_generic_phase
NGX_HTTP_SERVER_REWRITE_PHASE?? ?ngx_http_core_rewrite_phase
NGX_HTTP_FIND_CONFIG_PHASE?? ?ngx_http_core_find_config_phase
NGX_HTTP_REWRITE_PHASE?? ?ngx_http_core_rewrite_phase
NGX_HTTP_POST_REWRITE_PHASE?? ?ngx_http_core_post_rewrite_phase
NGX_HTTP_PREACCESS_PHASE?? ?ngx_http_core_generic_phase
NGX_HTTP_ACCESS_PHASE?? ?ngx_http_core_access_phase
NGX_HTTP_POST_ACCESS_PHASE?? ?ngx_http_core_post_access_phase
NGX_HTTP_TRY_FILES_PHASE?? ?ngx_http_core_try_files_phase
NGX_HTTP_CONTENT_PHASE?? ?ngx_http_core_content_phase
NGX_HTTP_LOG_PHASE?? ?ngx_http_core_generic_phase
Phase handler如何執(zhí)行
nginx在接收并解析完請求行,請求頭之后,就會依次調(diào)用各個phase handler.

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]);
? ? ? ? if (rc == NGX_OK) {
? ? ? ? ? ? return;
? ? ? ? }
? ? }
}
可以看到,其實依次執(zhí)行的就是我們在初始化階段,生成的ngx_http_phase_handler_t 數(shù)組

我們通過debug,來看一下ngx_http_phase_handler_t數(shù)組的實際內(nèi)容

運行中時ph數(shù)組的內(nèi)容
數(shù)組下標(biāo)?? ?checker?? ?handler?? ?next
0?? ?ngx_http_core_rewrite_phase?? ?ngx_http_rewrite_handler?? ?1
1?? ?ngx_http_core_find_config_phase?? ?0?? ?0
2?? ?ngx_http_core_rewrite_phase?? ?ngx_http_rewrite_handler?? ?3
3?? ?ngx_http_core_post_rewrite_phase?? ?0?? ?1
4?? ?ngx_http_core_generic_phase?? ?ngx_http_l7waf_handler?? ?7
5?? ?ngx_http_core_generic_phase?? ?ngx_http_limit_req_handler?? ?7
6?? ?ngx_http_core_generic_phase?? ?ngx_http_limit_conn_handler?? ?7
7?? ?ngx_http_core_access_phase?? ?ngx_http_access_handler?? ?10
8?? ?ngx_http_core_access_phase?? ?ngx_http_auth_basic_handler?? ?10
9?? ?ngx_http_core_post_access_phase?? ?0?? ?10
10?? ?ngx_http_core_try_files_phase?? ?0?? ?0
11?? ?ngx_http_core_content_phase?? ?ngx_http_index_handler?? ?14
12?? ?ngx_http_core_content_phase?? ?ngx_http_autoindex_handler?? ?14
13?? ?ngx_http_core_content_phase?? ?ngx_http_static_handler?? ?14
14?? ?0?? ?0?? ?0
我們來看一個具體的checker函數(shù)

ngx_int_t
ngx_http_core_generic_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
{
? ? ngx_int_t ?rc;
?
? ? /*
? ? ?* generic phase checker,
? ? ?* used by the post read and pre-access phases
? ? ?*/
?
? ? ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
? ? ? ? ? ? ? ? ? ?"generic phase: %ui", r->phase_handler);
?
? ? rc = ph->handler(r); ? ? ? ? ?// 執(zhí)行掛載的handler
?
? ? if (rc == NGX_OK) { ? ? ? ? ? // 返回值是NGX_OK,說明這個phase執(zhí)行完了,跳到下一個phase的第一個handler去
? ? ? ? r->phase_handler = ph->next;
? ? ? ? return NGX_AGAIN;
? ? }
?
? ? if (rc == NGX_DECLINED) { ? ? // 返回值NGX_DECLINED,繼續(xù)執(zhí)行這個phase的下一個handler
? ? ? ? r->phase_handler++;
? ? ? ? return NGX_AGAIN;
? ? }
?
? ? if (rc == NGX_AGAIN || rc == NGX_DONE) { //說明請求處理完了。下面所有的phase handler都不需要再執(zhí)行了
? ? ? ? return NGX_OK;
? ? }
?
? ? /* rc == NGX_ERROR || rc == NGX_HTTP_... ?*/
?
? ? ngx_http_finalize_request(r, rc); ? ? ? ?// 返回錯誤,結(jié)束請求,返回相應(yīng)的錯誤頁
?
? ? return NGX_OK;
}
?
如何選擇哪個phase
讀取請求內(nèi)容階段

這個階段沒有默認(rèn)的handler,主要用來讀取請求體,并對請求體做相應(yīng)的處理

Server請求地址重寫階段

這個階段主要是處理全局的(server block)的rewrite規(guī)則

配置查找階段

這個階段主要是通過uri來查找對應(yīng)的location。然后將uri和location的數(shù)據(jù)關(guān)聯(lián)起來。這個階段主要處理邏輯在checker函數(shù)中,不能掛載自定義的handler

Location請求地址重寫階段

這個主要處理location block的rewrite。

請求地址重寫提交階段

post rewrite,這個主要是進(jìn)行一些校驗以及收尾工作,以便于交給后面的模塊。這個phase不能掛載自定義handler

訪問權(quán)限檢查準(zhǔn)備階段

比如流控這種類型的access就放在這個phase,也就是說它主要是進(jìn)行一些比較粗粒度的access。

訪問權(quán)限檢查階段

這個比如存取控制,權(quán)限驗證就放在這個phase,一般來說處理動作是交給下面的模塊做的.這個主要是做一些細(xì)粒度的access。

訪問權(quán)限檢查提交階段

一般來說當(dāng)上面的access模塊得到access_code之后就會由這個模塊根據(jù)access_code來進(jìn)行操作 這個phase不能掛載自定義handler

配置項try_files處理階段

try_file模塊,也就是對應(yīng)配置文件中的try_files指令。 這個phase不能掛載自定義handler

按順序檢查文件是否存在,返回第一個找到的文件。結(jié)尾的斜線表示為文件夾 -$uri/。如果所有的文件都找不到,會進(jìn)行一個內(nèi)部重定向到最后一個參數(shù)。

內(nèi)容產(chǎn)生階段

內(nèi)容處理模塊,產(chǎn)生文件內(nèi)容,如果是php,去調(diào)用phpcgi,如果是代理,就轉(zhuǎn)發(fā)給相應(yīng)的后端服務(wù)器

日志模塊處理階段

日志處理模塊,是每個請求最后一定會執(zhí)行的。用于打印訪問日志。

通過如上對phase handler的分析,我們可以知道nginx劃分不同的phase,是將不同功能,安排在不同的順序執(zhí)行。

選擇掛載在哪個phase,就選擇了handler執(zhí)行的順序,并且選擇了不同的checker函數(shù)。

自定義的handler有時候可以掛載在不同的phase,都可以正常運行。

自定義的handler,如果依賴某一個phase的結(jié)果,則必須掛載在該phase后面的phase上。

自定義的handler需要遵守nginx對不同phase的功能劃分,但不是必需的。

除去4個不能掛載的phase,和log phase,還有如下6個phase可以掛載

NGX_HTTP_POST_READ_PHASE
NGX_HTTP_SERVER_REWRITE_PHASE
NGX_HTTP_REWRITE_PHASE
NGX_HTTP_PREACCESS_PHASE
NGX_HTTP_ACCESS_PHASE
NGX_HTTP_CONTENT_PHASE

很多功能掛載在這6個phase,都可以實現(xiàn)。掛載在越前面,我們的性能會越好,掛載在后面,我們的自由度會更大。

比如說,如果我們實現(xiàn)在NGX_HTTP_POST_READ_PHASE 階段,我們就不能用 location if 這些后面階段實現(xiàn)的指令來組合實現(xiàn)一些更復(fù)雜的功能。

推薦使用
NGX_HTTP_PREACCESS_PHASE
NGX_HTTP_ACCESS_PHASE
NGX_HTTP_CONTENT_PHASE
---------------------?
作者:囧囧有神?
來源:CSDN?
原文:https://blog.csdn.net/liujiyong7/article/details/38817135?
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請附上博文鏈接!

總結(jié)

以上是生活随笔為你收集整理的nginx phase handler的原理和选择的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: av影视网| 北条麻妃一区二区三区 | 久久久久亚洲AV成人无在 | 岛国av免费看 | 白石茉莉奈黑人 | 看全色黄大色黄大片大学生 | 国产男男gay网站 | 182tv福利视频 | 成人小视频在线播放 | 国产精品无码专区 | 天天操天天爽天天干 | 天堂一二三区 | 久久黄色大片 | 日本特级毛片 | 精品久久久久一区二区国产 | 做爰视频毛片视频 | 免费搞黄网站 | porn国产 | www激情| 97国产精品视频人人做人人爱 | 日韩久久久久久久久久久 | 一区二区三区欧美日韩 | 亚洲精品资源在线 | 一本一道波多野结衣av黑人 | 中文字幕视频二区 | 69免费视频 | www视频免费观看 | 免费的黄色的网站 | 玉女心经是什么意思 | 大象传媒成人在线观看 | 国产黄色片免费看 | 亚洲精品日本 | 一区二区三区免费看 | 日本激情网址 | 超碰www| 国产污视频在线播放 | 淫僧荡尼巨乳(h)小说 | 亚洲乱码中文字幕久久孕妇黑人 | 国产91在线播放 | 两性动态视频 | 国产小视频在线免费观看 | 中文字幕在线国产 | 成人免费版 | 欧美激情成人网 | 午夜亚洲av永久无码精品 | 五月天在线观看 | 欧洲一区二区 | 国产精品分类 | 一二三区免费 | 日美韩av| 国产精品v欧美精品v日韩 | 亚洲综合免费观看高清完整版在线 | 欧美色图88 | 亚洲精品电影网 | 少妇又色又爽又黄的视频 | 亚洲热在线视频 | 欧美天堂在线 | 日韩天堂一区 | xxxxx色 | 成人18在线 | 超碰在线国产97 | 国精产品一区一区三区视频 | 毛片大全在线观看 | 超碰人人人 | 亚洲午夜福利一区二区三区 | 五月天精品在线 | 精射女上司 | 日韩av无码一区二区三区 | 久久国产精品偷 | 午夜亚洲AV永久无码精品蜜芽 | 深夜福利在线免费观看 | 国产夜夜嗨 | av怡红院 | 自拍偷拍第二页 | 国产黄色大全 | 午夜国产视频 | 国产欧美熟妇另类久久久 | 污片网站在线观看 | 亚洲爱情岛论坛永久 | 天天天综合网 | 欧美系列在线观看 | 亚洲经典视频在线观看 | 色五夜 | 日本久久综合网 | 国产乱子一区二区 | 国产午夜久久 | 亚洲黄色三级 | 99久久99久久精品国产片 | 亚洲黄色中文字幕 | 午夜精品视频在线 | 天堂8av| 日韩欧美视频在线播放 | 日本精品中文字幕 | 国产精品久久久影院 | 好吊色这里只有精品 | 亚洲精品在线电影 | 久草国产在线视频 | 在线天堂中文字幕 | 久久艹这里只有精品 |