Nginx學(xué)習(xí):HTTP核心模塊(十二)內(nèi)嵌變量關(guān)于內(nèi)嵌變量,其實就是 Nginx 開放給我們的在配置文件中可以使用的變量。源碼中無非就是替換成真實的代碼變量進行操作。這些變量可以幫助我們做很多事情。之前的文章中其實也有不少地方用到了,比如說 $uri 這個變量,是不是已經(jīng)見過很多次了。而且這些變量基本上和 Apache 是對應(yīng)的。 默認提供的變量非常多,在這里我也只是將官網(wǎng)的 HTTP 核心模塊中提供的這些變量先列出來,然后盡已所能的借助工具翻譯一下。最常用的那些大家至少要知道是什么意思,而不常用的那些也可以隨時過來查閱。大部分自己使用 return 指令打印一下返回的結(jié)果看下效果就好了,特殊的我會單獨寫出來并加粗字體或者直接放上測試效果代碼。 $arg_[name] 請求行中的 name 參數(shù),注意這個 name 是可變的,指的就是 GET 參數(shù)。
// nginx.conf location /params1/ { return 200 $arg_a; }
// linux [root@localhost ~]# curl http://localhost/params1/?a=111 111
看出來效果了吧,直接可以獲得我們的 GET 參數(shù)中的某一個具體的參數(shù)。如果要獲取全部的參數(shù),就要使用下面的變量。 // nginx.conf location /params2/ { return 200 $args; }
// linux [root@localhost ~]# curl "http://localhost/params2/?a=111&b=222" a=111&b=222
$binary_remote_addr 客戶端IP地址的二進制形式,值的長度總是4字節(jié)的 IPv4 或者16字節(jié)的 IPv6 地址。$body_bytes_sent Nginx 返回給客戶端的字節(jié)數(shù),不含響應(yīng)頭。$bytes_sent nginx返回給客戶端的字節(jié)數(shù)。$connection 連接的序列號。這個連接是 Nginx 自己計數(shù)的,比如剛開機或者完全重啟 Nginx 就會從 1 開始,然后快速訪問重用 TCP 連接時也不會增加,大家可以自己試下哦。$connection_requests 當(dāng)前通過連接發(fā)出的請求數(shù)。啥意思呢?也是和連接有關(guān)的,指的是當(dāng)前這個 TCP 連接下的請求數(shù),如果是新開的一個 TCP 連接,就會歸零從1開始。用 CURL 和瀏覽器分別測試就很明顯。瀏覽器請求一次后等一會再試也可以看到效果,和之前我們講過的連接及長連接的內(nèi)容吻合。$connection_time 連接時間(以秒為單位,分辨率為毫秒)。當(dāng)前建立的 TCP 連接的持續(xù)連接時間。同樣的,新開 TCP 連接之后歸零,和上面的測試方式類似。$content_length “Content-Length” 請求頭的值。$content_type “Content-Type” 請求頭的值。$cookie_[name] 和第一個 $arg_[name] 一樣的,這里是獲取指定的 Cookie 的值。$document_root 當(dāng)前請求的 root 或者 alias 指令確定的目錄路徑。如果是相對路徑,比如 root html 那個,返回的也是完整的絕對路徑。$document_uri 和 $uri 是一樣的,之前我們就用過了,一會去那邊看。$host “Host” 請求頭的值,如果沒有該請求頭,則為與請求對應(yīng)的虛擬主機的首要主機名。$http_[name] 任意請求頭的值;變量名的后半部為轉(zhuǎn)化為小寫并且用下劃線替代橫線后的請求頭名稱。還是和 $arg_[name] 一樣,只不過這回是請求頭中指定的字段值。$https 如果連接是SSL模塊,返回 on ,否則返回空字符串。$is_args 如果請求行帶有參數(shù),返回 “?” ,否則返回空字符串。也就是說,有 GET 參數(shù)的話,這個變量的值就是個問號,如果沒有 GET 參數(shù)的話,它就是空的。$limit_rate 允許設(shè)置此值來限制連接的傳輸速率。之前在學(xué)習(xí)限流相關(guān)內(nèi)容的時候我們已經(jīng)了解過啦。$msec 當(dāng)前時間戳,單位是秒,精度是毫秒。(1.3.9, 1.2.6)$nginx_version Nginx 的版本號。$pid worker進程的PID,如果你當(dāng)前只有一個 worker 進程,那么可以修改下 worker_process 多設(shè)置幾個就能看出效果了。$pipe 如果當(dāng)前請求使用 pipeline 了,就會設(shè)置為 p ,否則的話就是 . 。這個 pipeline 也是 HTTP1.1 的一個特性,我也只是知道皮毛,這里就不多解釋了,大家可以自己查閱下相關(guān)的資料。$proxy_protocol_addr 通過代理協(xié)議獲取真實地址。這個和 HAProxy 這種四層代理服務(wù)器有關(guān),不在我們的討論范圍內(nèi)。簡單來說,就是四層負載轉(zhuǎn)發(fā)過來的請求,要拿到真實 IP 比較麻煩,不像 Nginx 做反向代理時可以直接設(shè)置頭。但如果使用 HAProxy 拋出的 Proxy Protocol 的話,就會簡單很多。這一塊的內(nèi)容我記下了,如果將來要學(xué)習(xí) HAProxy 相關(guān)的內(nèi)容的話,那么會再進行更詳細的測試與解讀。$proxy_protocol_port 和上面的一樣,不過是獲取端口號。$proxy_protocol_server_addr 通過代理協(xié)議獲取服務(wù)器地址。$proxy_protocol_server_port 通過代理協(xié)議,獲取服務(wù)器端口號。$query_string 和 $args 一樣。$realpath_root 按 root 或者 alias 配置算出的當(dāng)前請求的絕對路徑,如果有軟連接的文件也會解析成真實的文件路徑。這個比較常用,我這里就是默認的 /usr/local/nginx/html 這個目錄。$remote_addr 客戶端的 IP 地址。非常重要的,做反向代理的時候轉(zhuǎn)發(fā)真實 IP 地址就靠它了。$remote_port 客戶端的端口號。注意,是客戶端的,不是我們在 Nginx 用 listen 監(jiān)聽的。$request 完整的原始請求行。HTTP 請求中的第一行哦。$request_body 請求正文。只有通過 proxy_pass 或者 fastcgi_pass 相關(guān)配置路徑的路徑中,這個變量里面才有值。最常見的一個需求,將 POST 請求的參數(shù)也放到 access 日志中,就需要使用這個變量。注意,只有動態(tài)頁面才可以使用,因此才必須是需要 proxy_pass 或者 FastCGI 這些的路徑。$request_body_file 請求正文的臨時文件名。處理完成時,臨時文件被刪除。這個和我們之前講過的 client_body_in_file_only 參數(shù)有關(guān)。如果在被代理的請求或者 FastCGI 中傳遞臨時文件名,就應(yīng)該禁止傳遞請求正文。使用 proxy_pass_request_body off 配置和 fastcgi_pass_request_body off 配置來禁止傳遞普通的請求正文。$request_completion 請求完成時返回 ok ,否則返回空字符串。沒測試出效果,有了解的小伙伴可以留言哦。$request_filename 比較有用的一個變量,根據(jù) root 或者 alias 配置的路徑,以及請求的 URI ,得到當(dāng)前請求的完全文件路徑。$request_id 生成一個 16 字節(jié)的唯一哈希 ID ,在 1.11.0 版本之后才有的。$request_length 請求的長度,包括請求行、請求頭以及請求體的長度。$request_method 請求方法,就是 POST 、GET 那些啦,比較有用的。$request_time 請求處理的時間,單位為秒,精度是毫秒(1.3.9, 1.2.6),請求處理時間從由客戶端接收到第一個字節(jié)開始計算。$request_uri 返回原始的請求行(帶 GET 參數(shù)的),注意它和 $uri 以及 $document_uri 的區(qū)別。$scheme 請求協(xié)議的類型,比如 http 或 https 。$sent_http_[name] 響應(yīng)頭的信息,這個 name 可以替換成響應(yīng)頭的名稱,比如說 $sent_http_connection 就是響應(yīng)頭里面的 Connection 內(nèi)容。$sent_trailer_[name] 響應(yīng)結(jié)束時發(fā)送的任意字段(1.13.2),變量名的后半部分 name 可以替換成任意響應(yīng)頭的名稱。這個不太好測,需要使用日志,我們可以先在 http 模塊中定義一個自定義日志 log_format vvv op_trailer=$sent_trailer_op; 這一塊的內(nèi)容我們后面才會學(xué)到。然后在 location 中添加 add_trailer op 111; 以及 access_log logs/params2.log vvv; 。接著訪問鏈接之后,就可以在 /usr/local/nginx/logs 下面的 params2.log 日志文件中看到我們設(shè)置的內(nèi)容。$server_addr 接受請求的服務(wù)器地址。為計算這個值,通常需要進行一次系統(tǒng)調(diào)用。為了避免系統(tǒng)調(diào)用,必須指定listen 指令的地址,并且使用 bind 參數(shù)。我這里啥都沒配,就是顯示當(dāng)前服務(wù)器的 IP 地址。$server_name 接受請求的虛擬主機的首要主機名。server_name 配置指令的第一個主機名。$server_port 接受請求的虛擬主機的端口。$server_protocol 請求協(xié)議,通常為“HTTP/1.0 ”或“HTTP/1.1 ”。$status 返回響應(yīng)的狀態(tài)碼。$tcpinfo_rtt, $tcpinfo_rttvar, $tcpinfo_snd_cwnd, $tcpinfo_rcv_space 客戶端TCP連接的信息,在支持套接字選項TCP_INFO 的系統(tǒng)中可用。$time_iso8601 ISO 8601 標(biāo)準(zhǔn)的服務(wù)器當(dāng)前時間,我這里的結(jié)果是 2022-08-14T22:43:00-04:00 。$time_local 日志中的時間記錄變量,格式是 14/Aug/2022:22:43:00 -0400 。$uri 非常常用的,返回完整的 URI ,不包含 GET 參數(shù)。它值可能隨請求的處理過程而改變。 比如,當(dāng)進行內(nèi)部跳轉(zhuǎn)時,或者使用默認頁文件。
總結(jié)哈哈哈哈,是不是好簡單啊,水了一篇文章。不過雖說內(nèi)容少,但咱們可是一個一個真實地測了一下效果的,真不是從哪里復(fù)制粘貼來就完事了。 好了,這回真的要和 HTTP 核心模塊道別了,我們即將進入 HTTP 擴展模塊的學(xué)習(xí)了。說是擴展,但是其實也都是隨安裝包一起發(fā)布的,只需要在編譯安裝時的 configure 添加相應(yīng)的模塊即可,這一類的教程太多了,熟悉 Linux 安裝軟件的同學(xué)也都不會有問題。另外也有一部分模塊本身就包含在核心源碼中,只是區(qū)分出了不同的模塊分類。因此,咱們還是以配置指令的介紹學(xué)習(xí)為主,商業(yè)版部分的模塊也不在我們的學(xué)習(xí)范圍內(nèi)。 參考文檔: http:///en/docs/http/ngx_http_core_module.html
|