上一篇文章我寫了 Nginx 的 11 個階段,不少人都說太長了。這是出於文章完整性的考慮的,11 個階段嘛,一次性說完就完事了。今天這篇文章比較短,看完沒問題。html
以前咱們介紹了 Nginx 的 11 個階段,在 content 階段時,Nginx 會生成返回給用戶的響應內容,對用戶的響應內容,實際上還須要作再加工處理,Nginx 的過濾模塊就是對響應內容進行再加工處理的。因此實際上過濾模塊位於 content 階段以後,log 階段以前。nginx
咱們先來看一段配置指令:git
limit_req zone=req_one
burst=120;
limit_conn c_zone 1;
satisfy any;
allow 192.168.1.0/32;
auth_basic_user_file access.pass;
gzip on;
image_filter resize 80 80;
複製代碼
那麼在這一段配置指令之下,會遵循怎樣的請求流程呢?請看一下下面這張圖:github
上面這張圖的流程大體說一下,若是對於 Nginx 的 11 個階段不瞭解的去翻一下以前的文章。shell
我這裏再簡單說一下。首先由 Nginx 框架接收 HTTP 請求,通過 preaccess、access、content 階段的處理,當通過 static 模塊以後生成響應的時候,不少時候須要對響應進行處理,而後纔會返回給客戶端。數組
這裏咱們假如響應是一張圖片的話,那麼須要作縮略圖的時候,首先就要通過 image_filter 模塊的處理。這裏面還有一個 gzip 模塊,這兩個模塊也是須要遵循嚴格的順序的。由於若是先作 gzip 壓縮的話,縮略圖後面就沒辦法作了。瀏覽器
第二個須要關注的地方是,首先對 header 進行過濾,再對 body 進行過濾。由於咱們在對用戶發送響應的時候,必定是先發送 header,而後再發送 body,因此全部的過濾模塊都會提供對 header 或 body 的過濾,固然 image_filter 和 gzip 模塊對這二者均可以過濾。框架
前面咱們說過,Nginx 的 11 個階段是有嚴格的順序的,而這個順序是在 Nginx 的代碼中以一個數組的形式存在的,這個數組的順序是從後往前。在給用戶返回響應的時候,過濾模塊也是有嚴格順序的,這個順序一樣是從後往前。來看一下在代碼中的定義,標紅的是我下面會提到的幾個過濾模塊。curl
咱們須要重點關注四個過濾模塊,它們分別的做用是啥呢?post
copy_filter:複製包體內容
當咱們使用 sendfile 指令的時候,也就是零拷貝技術,不通過用戶態內存,這裏就是不通過 Nginx 直接發給用戶,同時也用了 gzip 模塊的時候,gzip 是必須在 copy_filter 模塊以後的,由於 gzip 必須對內存中的數據作壓縮,這時 copy_filter 就會讓 sendfile 指令失效。有些模塊不須要對內存中的數據進行處理,就須要在 copy_filter 模塊以前進行處理。
postpone_filter:處理子請求
用來處理子請求,有些過濾模塊須要關心子請求的處理結果,須要放在該模塊以後。
header_filter:構造響應頭部
用來構造最終發送給用戶的響應頭部,可能會添加一些 Server,Nginx 版本號等內容。
write_filter:發送響應
用來實際調用操做系統的 write 或 send 等系統調用,來把響應實際發送出去。
介紹完了過濾模塊的功能以及所處的階段,下面來具體看兩個模塊。
介紹一個能夠替換響應中字符串內容的模塊:sub 模塊。
ngx_http_sub_filter_module
模塊,默認未編譯進 Nginx,經過 --with-http_sub_module 啓用Syntax: sub_filter string replacement;
Default: —
Context: http, server, location
Syntax: sub_filter_last_modified on | off;
Default: sub_filter_last_modified off;
Context: http, server, location
Syntax: sub_filter_once on | off;
Default: sub_filter_once on;
Context: http, server, location
Syntax: sub_filter_types mime-type ...;
Default: sub_filter_types text/html;
Context: http, server, location
複製代碼
來解釋一下這四個指令都是啥意思。
sub_filter string replacement
sub_filter
指令會把匹配到的 string
字符串替換成 replacement
表示的字符串。
sub_filter_last_modified on | off
sub_filter_last_modified
指令的意思是,是否要返回原來的 last_modified
HTTP 頭部,由於咱們已經修改了文件內容,若是是 on
的話,就會繼續返回原來的頭部。
sub_filter_once on | off
sub_filter_once
的意思是,是否只替換一次,默認打開,若是設置爲 off
的話,那就會將響應中的內容所有掃描一遍並替換。
sub_filter_types mime-type
這個指令是說針對那些文件類型進行替換,這裏能夠設置成 *,可是效率就會比較低了,須要根據實際狀況考慮。
配置文件以下:
server {
server_name sub.ziyang.com;
error_log logs/myerror.log info;
location / {
sub_filter 'Nginx.oRg' '$host/nginx';
sub_filter 'nginX.cOm' '$host/nginx';
#sub_filter_once on;
sub_filter_once off;
#sub_filter_last_modified off;
sub_filter_last_modified on;
}
}
複製代碼
這裏須要從新編譯 Nginx,我這裏把下一節須要的模塊也一塊兒編譯進去了:
./configure --prefix=/Users/mtdp/myproject/nginx/test_nginx --with-http_sub_module --with-http_addition_module --with-http_realip_module
make
cp nginx ../../test_nginx/sbin/ # 複製編譯好的 nginx 到以前的目錄
複製代碼
執行熱部署:
熱部署的流程詳見 Nginx 入門及命令行操做
kill -USR2 87693 # 使用新的 Nginx 二進制文件提供服務
kill -WINCH 87693 # 退出老的 Nginx 的 worker 進程
kill -quit 87693 # 優雅的退出老的 master 進程
複製代碼
在瀏覽器中打開 sub.ziyang.com:
這裏面會發現,nginx.org 已經替換成了 sub.ziyang.com/nginx,nginx.com 也替換成了 sub.ziyang.com/nginx。
下面再來看一個過濾模塊,addition 模塊,它能夠在響應的先後添加內容。
功能:在相應前或者響應後增長內容,增長內容的方式,是經過新增子請求,根據子請求的響應來完成。
模塊:ngx_http_addition_filter_module
默認未編譯進 Nginx,經過 --with-http_addition_module 啓用
Syntax: add_before_body uri;
Default: —
Context: http, server, location
Syntax: add_after_body uri;
Default: —
Context: http, server, location
Syntax: addition_types mime-type ...;
Default: addition_types text/html;
Context: http, server, location
複製代碼
這裏的三個指令都比較簡單,說一下 add_before_body
和 add_after_body
後面的 uri
,這個的意思是說,向指定 uri
發起子請求,根據子請求的響應來添加內容。
addition_types
指令是指定要添加的文件類型。
配置文件以下:
server {
server_name addition.ziyang.com;
error_log logs/myerror.log info;
location / {
#add_before_body /before_action;
#add_after_body /after_action;
#addition_types *;
}
location /before_action {
return 200 'new content before\n';
}
location /after_action {
return 200 'new content after\n';
}
location /testhost {
uninitialized_variable_warn on;
set $foo 'testhost';
return 200 '$gzip_ratio\n';
}
}
複製代碼
先看在註釋掉 addition 模塊的指令的狀況下,會是什麼效果:
➜ ~ curl addition.ziyang.com/a.txt
a
複製代碼
而後打開註釋:
➜ ~ curl addition.ziyang.com/a.txt
new content before
a
new content after
複製代碼
在原響應先後都增長了內容。
這裏面須要注意一點,在實際狀況下,add_before_body
和 add_after_body
後面是其餘的 uri,我這裏爲了簡化,直接轉發到對應的 location。
本文涉及到的全部配置文件我已經放在了 Nginx 配置文件,你們能夠自取。