openresty开发系列31--openresty执行流程
openresty開發(fā)系列31--openresty執(zhí)行流程
我們先看個例子
location /test {
?? ?set $a 32;
?? ?echo $a;
?? ?set $a 56;
?? ?echo $a;
}
echo nginx第三方模塊,是用于做響應輸出
輸出了 56
Nginx 處理每一個用戶請求時,都是按照若干個不同階段依次處理的。而不是根據(jù)配置文件上的順序。
之上的例子 涉及到了 兩個階段? rewrite和content階段
set屬于rewrite階段
echo屬于content階段
而且 rewrite階段的指令 在 content階段指令 之前執(zhí)行。
實際的執(zhí)行順序應當是
??? set $a 32;
??? set $a 56;
??? echo $a;
??? echo $a;
所以輸出 56
在我們配置文件中執(zhí)行的指令,可以理解為對我們的執(zhí)行階段進行入棧
Nginx處理請求的過程一共劃分為11個階段,按照執(zhí)行順序依次是post-read、server-rewrite、
find-config、rewrite、post-rewrite、 preaccess、access、post-access、try-files、content、log.
1、post-read
讀取請求內(nèi)容階段,nginx讀取并解析完請求頭之后就立即開始運行;
例如模塊 ngx_realip 就在 post-read 階段注冊了處理程序,
它的功能是迫使 Nginx 認為當前請求的來源地址是指定的某一個請求頭的值。
2、server-rewrite
server請求地址重寫階段;當ngx_rewrite模塊的set配置指令直接書寫在server配置塊中時,
基本上都是運行在server-rewrite 階段
3、find-config
配置查找階段,這個階段并不支持Nginx模塊注冊處理程序,
而是由Nginx核心來完成當前請求與location配置塊之間的配對工作。
4、rewrite
location請求地址重寫階段,當ngx_rewrite指令用于location中,就是再這個階段運行的;
另外ngx_set_misc(設(shè)置md5、encode_base64等)模塊的指令,
還有ngx_lua模塊的set_by_lua指令和rewrite_by_lua指令也在此階段。
5、post-rewrite
請求地址重寫提交階段,當nginx完成rewrite階段所要求的內(nèi)部跳轉(zhuǎn)動作,如果rewrite階段有這個要求的話;
6、preaccess
訪問權(quán)限檢查準備階段,ngx_limit_req和ngx_limit_zone在這個階段運行,
ngx_limit_req可以控制請求的訪問頻率,ngx_limit_zone可以控制訪問的并發(fā)度;
7、access
訪問權(quán)限檢查階段,標準模塊ngx_access、第三方模塊ngx_auth_request以及第三方模塊ngx_lua的access_by_lua
指令就運行在這個階段。配置指令多是執(zhí)行訪問控制相關(guān)的任務,如檢查用戶的訪問權(quán)限,檢查用戶的來源IP是否合法;
8、post-access
訪問權(quán)限檢查提交階段;主要用于配合access階段實現(xiàn)標準ngx_http_core模塊提供的配置指令satisfy的功能。
satisfy all(與關(guān)系),satisfy any(或關(guān)系)
9、try-files
配置項try_files處理階段;專門用于實現(xiàn)標準配置指令try_files的功能,
如果前 N-1 個參數(shù)所對應的文件系統(tǒng)對象都不存在,
try-files 階段就會立即發(fā)起“內(nèi)部跳轉(zhuǎn)”到最后一個參數(shù)(即第 N 個參數(shù))所指定的URI.
10、content
內(nèi)容產(chǎn)生階段,是所有請求處理階段中最為重要的階段,
因為這個階段的指令通常是用來生成HTTP響應內(nèi)容并輸出 HTTP 響應的使命;
11、log
日志模塊處理階段;記錄日志
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)限檢查準備階段
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:
??? #日志模塊處理階段 常用
到此,應該明白Nginx 的conf中指令的書寫順序和執(zhí)行順序是兩碼事,切記。
有些階段是支持 Nginx 模塊注冊處理程序,有些階段并不可以。
最常用的是 rewrite階段,access階段 以及 content階段;
不支持 Nginx 模塊注冊處理程序的階段 find-config, post-rewrite, post-access,
主要是 Nginx 核心完成自己的一些邏輯。
Nginx下Lua處理階段與使用范圍
openresty發(fā)起一個請求時,會有相應的執(zhí)行流程
如圖
從圖中可知,OpenResty 處理請求大致分為四個階段:
1)初始化階段(Initialization Phase)
2)重寫與訪問階段(Rewrite / Access Phase)
3)內(nèi)容生成階段(Content Phase)
4)日志記錄階段(Log Phase)
我們OpenResty做個測試,示例代碼如下:
init_by_lua 'ngx.log(ngx.ERR, "init_by_lua")';
?? ?
init_worker_by_lua 'ngx.log(ngx.ERR, "init_worker_by_lua")';
?? ?
server { ?
??? listen 80; ?
?? ??? ??? ?
?? ?location /exec {
?? ??? ?rewrite_by_lua 'ngx.log(ngx.ERR, "rewrite_by_lua")';
?? ??? ?set_by_lua $a 'ngx.log(ngx.ERR, "set_by_lua")';
?? ??? ?access_by_lua 'ngx.log(ngx.ERR, "access_by_lua")';
?? ??? ?header_filter_by_lua 'ngx.log(ngx.ERR, "header_filter_by_lua")';
?? ??? ?body_filter_by_lua 'ngx.log(ngx.ERR, "body_filter_by_lua")';
?? ??? ?log_by_lua 'ngx.log(ngx.ERR, "log_by_lua")';
?? ??? ?content_by_lua 'ngx.log(ngx.ERR, "content_by_lua")';
?? ?}
} ?
這幾個階段的存在,應該是openresty不同于其他多數(shù)Web server編程的最明顯特征了。
由于nginx把一個會話分成了很多階段,這樣第三方模塊就可以根據(jù)自己行為,掛載到不同階段進行處理達到目的。
這樣我們就可以根據(jù)我們的需要,在不同的階段直接完成大部分典型處理了。
指令可以在http、server、server if、location、location if幾個范圍進行配置:
指令 ?? ??? ??? ??? ??? ??? ?所處處理階段 ?? ??? ?使用范圍 ?? ??? ??? ?解釋
init_by_lua
init_by_lua_file ?? ??? ??? ?loading-config ?? ??? ?http ?? ??? ??????? ?
nginx Master進程加載配置時執(zhí)行;通常用于初始化全局配置/預加載Lua模塊
init_worker_by_lua
init_worker_by_lua_file ?? ?starting-worker ?? ?http ?? ??? ??? ??? ?
每個Nginx Worker進程啟動時調(diào)用的計時器,如果Master進程不允許則只會在init_by_lua之后調(diào)用;
通常用于定時拉取配置/數(shù)據(jù),或者后端服務的健康檢查
set_by_lua
set_by_lua_file ?? ??? ??? ?rewrite ?? ??? ?server,server if,location,location if
設(shè)置nginx變量,可以實現(xiàn)復雜的賦值邏輯;此處是阻塞的,Lua代碼要做到非常快;
rewrite_by_lua
rewrite_by_lua_file ?? ??? ?rewrite tail ?? ?http,server,location,location if
rrewrite階段處理,可以實現(xiàn)復雜的轉(zhuǎn)發(fā)/重定向邏輯;
access_by_lua
access_by_lua_file ?? ??? ??? ?access tail ?? ?http,server,location,location if ?? ?
請求訪問階段處理,用于訪問控制
content_by_lua
content_by_lua_file ?? ??? ?content ?? ??? ?location,location if
內(nèi)容處理器,接收請求處理并輸出響應
header_filter_by_lua
header_filter_by_lua_file ?? ?output-header-filter ?? ?http,server,location,location if
響應 HTTP過濾處理(例如添加頭部信息),設(shè)置header和cookie
body_filter_by_lua
body_filter_by_lua_file ?? ?output-body-filter ?? ??? ?http,server,location,location if
響應 BODY過濾處理(例如完成應答內(nèi)容統(tǒng)一成大寫) 對響應數(shù)據(jù)進行過濾,比如截斷、替換。
log_by_lua
log_by_lua_file ?? ??? ??? ?log ?? ??? ??? ??? ??? ?http,server,location,location if
響應完成后本地異步完成日志記錄(日志可以記錄在本地,還可以同步到其他機器)
階段處理,比如記錄訪問量/統(tǒng)計平均響應時間
實際上我們只使用其中一個階段content_by_lua,也可以完成所有的處理。但這樣做,
會讓我們的代碼比較臃腫,越到后期越發(fā)難以維護。把我們的邏輯放在不同階段,分工明確,代碼獨立
轉(zhuǎn)載于:https://www.cnblogs.com/reblue520/p/11446297.html
總結(jié)
以上是生活随笔為你收集整理的openresty开发系列31--openresty执行流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: kettle的安装与连接mysql(包含
- 下一篇: openresty开发系列32--ope