本小節(jié)罕模,我們將主要介紹 Nginx 中 Http 請求 11 個階段中的最后幾個重要的階段以及相關(guān)的模塊橄唬,并演示其用法。
1. try_files 階段
這個階段又稱為 precontent 階段,是 content 階段的前置處理階段雷则,該階段主要介入的模塊是 ngx_http_try_files_module 模塊。該模塊依次訪問多個 URI 對應得文件(由 root 或者 alias 指令指定)肪笋,當文件存在時直接返回內(nèi)容月劈,如果所有文件不存在,則按最后一個 URL 結(jié)果或者 code 返回藤乙。
Syntax: try_files file ... uri;
try_files file ... =code;
Default: —
Context: server, location
2. content 階段
content 階段中最主要的 static 模塊猜揪,該模塊提供了root 和 alias 這兩個常用的指令。二者的用法如下:
Syntax: alias path
Default: —
Context: location
Syntax: root path
Default: root html
Context: http, server, location, if in location
可以看到坛梁,單從指令用法上就可以看到不少區(qū)別而姐,首先是 alias 指令沒有默認值,而且該指令只能在 location 中使用划咐。而 root 可以存在與 http拴念、server、location 等多個指令塊中褐缠,還可以出現(xiàn)在 if 指令中政鼠。另外,最最主要的不同是兩個指令會以不同的方式將請求映射到服務器文件上队魏。root 指令會用[root 路徑 + location 路徑]的規(guī)則映射靜態(tài)資源請求公般,而 alias 會使用 alias 的路徑替換 location 路徑。
此外 alias 后面必須要用“/”結(jié)束胡桨,否則會找不到文件的俐载,而 root 則可有可無。來看下面一個例子:
location ^~ /test {
root /root/html/;
}
location ^~ /test2/ {
alias /root/html/;
}
對于 http 請求: http://ip:端口/test/web1.html
訪問的是主機 上全路徑為 /root/html/test/web1.html
的靜態(tài)資源登失;而請求http://ip:端口/test2/web1.html
訪問的是全路徑為/root/html/web1.html
的靜態(tài)資源遏佣,/test2/已經(jīng)被替換掉了。
在 static 模塊中揽浙,還提供了 3 個變量供我們使用状婶,分別是:
- request_filename: 訪問靜態(tài)資源的完整路徑
- document_root: 訪問靜態(tài)資源文件所在目錄
- realpath_root: 如果 document_root 是軟鏈接,則改變量會將其替換成真正的地址
同樣是上面的例子馅巷,稍做改動:
location /web {
default_type text/html;
alias /root/test/web;
return 200 '$request_filename:$document_root:$realpath_root\n';
}
訪問 http://ip:端口//web/web1.html
, 返回的結(jié)果為:
/root/test/web/web1.html:/root/test/web:/root/test/web
在 content 階段膛虫,在 static 模塊之前,還會執(zhí)行的模塊有 index 和 autoindex模塊钓猬。index 模塊提供了 index 指令稍刀,用于指定/訪問時返回 index 文件內(nèi)容。
autoindex 模塊會根據(jù)配置決定是否以列表的形式展示目錄下的內(nèi)容,這個功能在后續(xù)實戰(zhàn)中搭建內(nèi)部 pip 源中會用到账月。
Syntax: index file ...;
Default: index index.html;
Context: http, server, location
# 示例综膀,訪問 uri=/ 時,返回靜態(tài)資源 index.html 文件中的內(nèi)容
location / {
index index.html;
}
# 是否開啟目錄顯示局齿,默認Nginx是不會顯示目錄下的所有文件
Syntax: autoindex on | off;
Default: autoindex off;
Context: http, server, location
# 顯示出文件的實際大小
Syntax: autoindex_exact_size on | off;
Default: autoindex_exact_size on;
Context: http, server, location
# 顯示格式剧劝,默認是html形式顯示
Syntax: autoindex_format html | xml | json | jsonp;
Default: autoindex_format html;
Context: http, server, location
# 顯示時間,設(shè)置為on后抓歼,按照服務器的時鐘為準
Syntax: autoindex_localtime on | off;
Default: autoindex_localtime off;
Context: http, server, location
3. log 階段
log 階段是 http 請求 11 個階段中的最后一個階段讥此,這個階段主要的任務就是記錄請求的訪問日志。這個階段主要涉及的是 ngx_http_log_module 這個模塊谣妻。該模塊提供了幾個常用指令萄喳,如 access_log 和 log_format 指令,分別定義了請求日志的記錄文件以及記錄的日志格式蹋半。
# 官方例子
log_format compression '$remote_addr - $remote_user [$time_local] '
'"$request" $status $bytes_sent '
'"$http_referer" "$http_user_agent" "$gzip_ratio"';
access_log /spool/logs/nginx-access.log compression buffer=32k;
# access_log指令用法
Syntax: access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
Default: access_log logs/access.log combined;
Context: http, server, location, if in location, limit_except
# log_format指令用法
Syntax: log_format name [escape=default|json|none] string ...;
Default: log_format combined "...";
Context: http
# 是否打開日志緩存
Syntax: open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
Default: open_log_file_cache off;
Context: http, server, location
4. 案例測試
4.1 try_files 模塊的示例
在測試機器的 /root/test/web 目錄下有 2 個 html 文件取胎,分別為 web.html 和 web2.html, 沒有 web3.html湃窍。我們編寫如下的 server 塊闻蛀,監(jiān)聽 8013 端口。首先訪問 http://主機ip:8013/web 時您市,根據(jù)配置情況觉痛,Nginx 首先查找是否存在 /root/test/web/web3.html 文件,沒有找到會繼續(xù)向下茵休,找$uri薪棒,也就是/root/test/web 文件,不存在榕莺。繼續(xù)找 KaTeX parse error: Expected 'EOF', got '俐芯,' at position 15: uri/index.html,?即/root/test/web…uri/web1.html時文件存在钉鸯,故返回/root/test/web/web1.html文件內(nèi)容吧史。如果該文件還不存在,則還會繼續(xù)批評額哦@lasturi唠雕,最后返回’lasturi!'這樣的字符串贸营。而在訪問 http://主機ip:8013/return_code 時,由于無法匹配靜態(tài)資源岩睁,根據(jù)配置最后返回404錯誤碼钞脂,出現(xiàn) Nginx 默認的 404 錯誤頁面。
server {
server_name try_files.com;
listen 8013;
root /root/test/;
default_type text/plain;
location /web {
# 找/root/test/index.html
# try_files /index.html
try_files /web/web3.html
$uri $uri/index.html $uri/web1.html
@lasturi; #最后匹配這個
}
location @lasturi {
eturn 200 'lasturi!\n';
}
location /return_code {
try_files $uri $uri/index.html $uri.html =404;
}
}
4.2 access_log 指令用法示例
我們只需要在 http 指令塊中配置 log_format 指令和 access_log 指令即可捕儒。測試的配置如下:
...
http {
...
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
# 和上面的日志格式無關(guān)
server {
listen 8000;
return 200 '8000, server\n';
}
...
}
...
log_format 指令是指定打印日志的格式冰啃,access_log 指令指定日志輸出的路徑以及指定使用前面定義的日志格式。在配置好日志相關(guān)的指令后,重啟 Nginx阎毅,并發(fā)送一個 Http 請求焚刚,就可以在對應的路徑上看到相關(guān)的日志信息了。
# 模擬發(fā)送http請求
[shen@shen Desktop]$ curl http://180.76.152.113:8000
8000, server
[shen@shen Desktop]$ curl -H "X-Forwarded-For: 1.1.1.1" http://180.76.152.113:8000
# 查看打印的日志净薛,和前面配置的日志格式進行對比
[root@server nginx]# tail -2 logs/access.log
103.46.244.226 - - [02/Feb/2020:20:52:05 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "-"
103.46.244.226 - - [02/Feb/2020:20:57:03 +0800] "GET / HTTP/1.1" 200 13 "-" "curl/7.29.0" "1.1.1.1"
5. 小結(jié)
本節(jié)內(nèi)容介紹了 Http 請求 11 個階段中的最后幾個,分別是 try_files 階段蒲拉、content 階段和 log 階段肃拜,同時還有對應階段中生效的指令。這些在配置靜態(tài)資源訪問時非常有用雌团,因為主要是涉及到讀取靜態(tài)資源的內(nèi)容燃领。最后的 log 模塊也是非常重要的一步,良好的日志記錄有助于我們后續(xù)排查問題以及分析系統(tǒng)性能瓶頸锦援。今天 Http 請求的 11 個處理階段正式講完猛蔽,后面還需要多多深入每個階段的指令學習和實驗,徹底掌握 Nginx 的 Http 模塊灵寺。