計(jì)算機(jī)網(wǎng)站的開(kāi)發(fā)流程湖南百度推廣
Nginx學(xué)習(xí):HTTP核心模塊(十)Types、AIO及其它配置
今天學(xué)習(xí)的內(nèi)容也比較簡(jiǎn)單,主要的是 Types 相關(guān)的配置,另外還會(huì)了解一下 AIO 以及部分沒(méi)有特別大的分類歸屬的配置指令的使用。后面的內(nèi)容都是 HTTP 核心模塊中比較小或者比較簡(jiǎn)單的部分了。有很多配置項(xiàng)其實(shí)我們平常并不常用,甚至很多在學(xué)習(xí)之前我都不知道有它們的存在。做為擴(kuò)展知識(shí)眼界來(lái)說(shuō),非常有意義,也能夠?qū)W習(xí)到很多之前并不了解或者概念模糊的內(nèi)容。
Types
這是啥?類型?是的,真的就是類型的意思,不過(guò)它指的是我們請(qǐng)求訪問(wèn)的資源類型。大家應(yīng)該都了解,最初的互聯(lián)網(wǎng)就是靜態(tài)頁(yè)面,而靜態(tài)頁(yè)面對(duì)應(yīng)的就是一個(gè)個(gè)的實(shí)實(shí)在在的文件。只不過(guò)隨著技術(shù)的發(fā)展,動(dòng)態(tài)頁(yè)面通過(guò)各種后端語(yǔ)言占據(jù)了主導(dǎo)地位。但對(duì)于很多資源來(lái)說(shuō),比如圖片、視頻這類大型資源,還有 js、css 這類文件,以及前后端分離的前端部分,還是會(huì)通過(guò)普通文件的形式進(jìn)行部署訪問(wèn)。
那么在請(qǐng)求資源的時(shí)候,瀏覽器是怎么知道要以何種方式解析某個(gè)文件呢?比如說(shuō),我們?cè)L問(wèn)一個(gè) .mp3 結(jié)尾的鏈接,現(xiàn)在的瀏覽器都會(huì)直接展示一個(gè)播放器讓大家可以直接聽(tīng)歌。這就是通過(guò) MIME 類型來(lái)實(shí)現(xiàn)的。
最典型的就是對(duì)于普通網(wǎng)頁(yè),響應(yīng)頭中會(huì)返回一個(gè)?Content-Type: text/html;
?的內(nèi)容。它就是告訴瀏覽器要用什么方式來(lái)處理當(dāng)前響應(yīng)返回的數(shù)據(jù)。
類似的還有 text/css、image/gif、image/jpeg、image/gif、text/plain、application/javascript、application/json、application/octet-stream、audio/mpeg、video/mp4 等等。具體都是什么意思就不多解釋了,大家應(yīng)該都多少有過(guò)了解。這些內(nèi)容,其實(shí)在 Nginx 的配置文件中就有。
……
http{
……
include???????mime.types;
……
}
在大部分默認(rèn)的 nginx.conf 文件中,應(yīng)該都可以找到這樣一個(gè) include 語(yǔ)句。之前我們已經(jīng)學(xué)習(xí)過(guò) include 可以加載一個(gè)文件進(jìn)來(lái),這個(gè)文件的配置信息就會(huì)被嵌入到 include 的這個(gè)位置。那么我們就再來(lái)看看這個(gè) mime.types 文件是啥。
在 nginx.conf 所在的同級(jí)目錄中找到 mime.types 文件,打開(kāi)它就會(huì)發(fā)現(xiàn)它定義了很多內(nèi)容。
types{text/html????????????????????????????????????????html?htm?shtml;text/css?????????????????????????????????????????css;text/xml?????????????????????????????????????????xml;image/gif…………video/x-ms-asf???????????????????????????????????asx?asf;video/x-ms-wmv???????????????????????????????????wmv;video/x-msvideo??????????????????????????????????avi;
}
可以看到,它也是一個(gè)類似于小模塊一樣的配置,有一對(duì)花括號(hào)。里面定義的其實(shí)是文件擴(kuò)展名與響應(yīng)的 MIME 類型的映射表。也就是說(shuō),后面對(duì)應(yīng)的文件后綴名,在返回響應(yīng)的時(shí)候就會(huì)響應(yīng)成前面的 MIME 碼。如果有特殊需要,你也可以自己修改或者添加不同的 MIME 。
default_type
定義響應(yīng)的默認(rèn)MIME類型。
default_type?mime-type;
默認(rèn)值是 text/plain ,但直接安裝后都會(huì)給一個(gè) application/octet-stream 。其實(shí)也就是在 types 中找不到類型,就會(huì)走這個(gè)默認(rèn)值。我們可以來(lái)簡(jiǎn)單測(cè)試下。
location?/mimetest/?{alias?/usr/local/nginx/html/;types?{}default_type?text/plain;
}
配置一個(gè) /mimetest 的 location ,然后將 types{} 設(shè)置為 空的。types 可以設(shè)置在 http、server、location 下,以最下層的為準(zhǔn)。然后設(shè)置 default_type 為 text/plain 。現(xiàn)在訪問(wèn) /mimetest ,就會(huì)發(fā)現(xiàn)默認(rèn)的 index.html 會(huì)以文本的形式直接輸出出來(lái) ,包括 html 標(biāo)簽。
另外,假如有專門的下載路徑,我們也可以這樣配置,強(qiáng)制走這個(gè)路徑的所有請(qǐng)求都走下載。
location?/download/?{alias?/usr/local/nginx/html/;types????????{?}default_type?application/octet-stream;
}
types_hash_bucket_size
設(shè)置MIME類型哈希桶大小,其默認(rèn)值取決于處理器的緩存線長(zhǎng)度。
types_hash_bucket_size?size;
默認(rèn)值取決于處理器緩存線的大小,將來(lái)學(xué)習(xí)哈希表的時(shí)候再說(shuō)。
types_hash_max_size
設(shè)置MIME類型哈希表的最大size(容量)。
types_hash_max_size?size;
默認(rèn)值是 1024, 將來(lái)學(xué)習(xí)哈希表的時(shí)候再說(shuō)。
AIO
AIO 是啥東西?它是 Linux 和 FreeBSD 這類操作系統(tǒng)下的一種異步 IO 功能。它的作用是可以允許進(jìn)程發(fā)起很多 IO 操作,而不用阻塞或等待任何操作完成。稍后在收到 IO 操作完成的通知時(shí),進(jìn)程就可以檢索 IO 操作的結(jié)果。注意,它和 epoll 不是一個(gè)東西,是操作系統(tǒng)的 aio 系列函數(shù)調(diào)用。而且 Nginx 中可以組合 aio 和 epoll 來(lái)一起使用。AIO 相關(guān)的配置項(xiàng)都可以用于 http、server、location 各個(gè)模塊中。
aio
aio?on?|?off?|?sendfile;
這個(gè)配置的默認(rèn)值是 off 。另外還可以設(shè)置為 on 和 sendfile 。sendfile 只能用于 FreeBSD 5.2.1 之后的系統(tǒng)中,之前的版本和 Linux 下需要關(guān)閉 sendfile 。在 FreeBSD 第5版和第6版,靜態(tài)啟動(dòng) AIO ,或者在系統(tǒng)啟動(dòng)時(shí)動(dòng)態(tài)加載 AIO ,都會(huì)觸發(fā)網(wǎng)絡(luò)子系統(tǒng)使用一把大鎖,進(jìn)而對(duì)整個(gè)系統(tǒng)的性能造成負(fù)面影響。這個(gè)限制在 2009 年發(fā)布的 FreeBSD 6.4穩(wěn)定版和 FreeBSD 7 中被消除。雖然如此,仍有方法在 5.3 及以上版本的 FreeBSD 中開(kāi)啟 AIO 而不觸發(fā)網(wǎng)絡(luò)子系統(tǒng)的大鎖,那就是在內(nèi)核啟動(dòng)以后加載AIO模塊。
如果是在 Linux 系統(tǒng)中,使用 AIO 需要同時(shí)開(kāi)啟 directio 配置項(xiàng),并且 directio 的配置必須是 512 才有效,啟用了 directio 會(huì)自動(dòng)關(guān)閉 sendfile。為什么它們兩個(gè)不兼容呢?其實(shí) AIO 是將數(shù)據(jù)讀到緩沖區(qū),而 sendfile 則是直接將數(shù)據(jù)發(fā)送走,因此,這倆貨是對(duì)頭,沒(méi)法一起使用。FreeBSD 系統(tǒng)從來(lái)沒(méi)用過(guò),也不知道它為什么可以讓 AIO 和 sendfile 并存,這個(gè)也不在我們的討論范圍內(nèi)了。
aio_write
aio_write?on?|?off;
這個(gè)指令是 aio 的一個(gè)附屬指令,表示如果啟用 aio 的話,則指定它是否用于寫(xiě)入文件。目前,這僅在使用aio線程時(shí)有效,并且僅限于使用從代理服務(wù)器接收的數(shù)據(jù)寫(xiě)入臨時(shí)文件。
如果開(kāi)啟了 AIO ,那么 Nginx 中會(huì)將 aio 和 epoll 事件模型(假設(shè) Nginx 使用 epoll 事件模型)組合起來(lái)使用,當(dāng)請(qǐng)求的 IO 操作完成時(shí)調(diào)用 epoll 相關(guān)函數(shù)通知應(yīng)用程序來(lái)讀取。根據(jù) Nginx 官網(wǎng)論壇來(lái)看,在 Linux 系統(tǒng)的大部分場(chǎng)景下,目前因使用 AIO 功能附加的限制而帶來(lái)的實(shí)際效果并不太理想。而且這個(gè)我也不知道咋測(cè),直接壓力測(cè)試嘛?算了,咱們也不測(cè)了,平常保持默認(rèn)的關(guān)閉好了。
關(guān)于 AIO 更詳細(xì)的資料還是需要去深入的學(xué)習(xí)一下操作系統(tǒng)相關(guān)的知識(shí),在這里我也就不深究了,記下這一筆,將來(lái)深入的學(xué)習(xí)操作系統(tǒng)時(shí)再進(jìn)行詳細(xì)的學(xué)習(xí)。
其它
這些配置指令沒(méi)有大的歸屬,不過(guò)也有一些是比較常見(jiàn)的,下篇文章也會(huì)繼續(xù)講一些其它配置指令,今天先來(lái)看一部分。
auth_delay
主要是權(quán)限配置相關(guān)的,當(dāng)我們配置并使用了 auth_basic、auth_request 或者 auth_jwt 相關(guān)的模塊時(shí),定義一個(gè)超時(shí)時(shí)間,用于防止定時(shí)攻擊。
auth_delay?time;
默認(rèn) 0s ,其實(shí)也就是沒(méi)有開(kāi)啟。定時(shí)攻擊其實(shí)也叫時(shí)序攻擊,根據(jù)加密的不同,我們?cè)诩用苓^(guò)程中的返回速度是不一樣,但是也已經(jīng)有很多加密算法是可以預(yù)防時(shí)序攻擊的,之前在?PHP的Hash信息摘要擴(kuò)展框架https://mp.weixin.qq.com/s/1qAkPkMWcxq_kIoq8b2vOw?這篇文章中我們就已經(jīng)學(xué)習(xí)過(guò),這里就不多說(shuō)了。
Nginx 可以通過(guò)這個(gè)命令來(lái)保證超過(guò)指定加密時(shí)間直接返回一個(gè) 401 錯(cuò)誤,具體就不演示了,因?yàn)槲乙膊恢勒ρ菔尽?/p>
chunked_transfer_encoding
允許關(guān)閉HTTP/1.1中的分塊傳輸編碼。
chunked_transfer_encoding?on?|?off;
默認(rèn)值是 on ,在客戶端軟件不支持分塊傳輸編碼或者不希望使用分塊傳輸?shù)臅r(shí)候,這條指令可以關(guān)掉它。自己試了半天,也不知道咋測(cè),有了解的小伙伴可以留言哦!
connection_pool_size
允許微調(diào)為每個(gè)連接分配的內(nèi)存。
connection_pool_size?size;
這條指令對(duì) Nginx 的性能影響非常小,一般不應(yīng)該使用。默認(rèn)情況下,該大小在 32 位平臺(tái)上等于 256 字節(jié),在 64 位平臺(tái)上等于 512 字節(jié)。在 1.9.8 版本之前,所有平臺(tái)上的默認(rèn)值均為 256 。
log_not_found
開(kāi)啟或者關(guān)閉在 error_log 中記錄文件不存在的錯(cuò)誤。
log_not_found?on?|?off;
默認(rèn)值是 on ,這個(gè)配置主要就是我們?cè)L問(wèn)一個(gè)不存在的頁(yè)面,找不到對(duì)應(yīng)的文件,一般會(huì)報(bào)出一個(gè) 404 錯(cuò)誤,并且對(duì)應(yīng)的 error_log 日志文件中會(huì)記錄一條信息。
2022/08/07?20:52:41?[error]?868#0:?*1?open()?"/usr/local/nginx/html/123.html"?failed?(2:?No?such?file?or?directory),?client:?192.168.56.1,?server:?core.nginx.test,?request:?"GET?/123.html?HTTP/1.1",?host:?"192.168.56.88"
但如果我們將它設(shè)置為 off ,則在錯(cuò)誤日志中就不會(huì)記錄這條信息了,只會(huì)在 access_log 中記錄那個(gè) 404 的請(qǐng)求。
log_subrequest
開(kāi)啟或者關(guān)閉在 access_log 中記錄子請(qǐng)求的訪問(wèn)日志
log_subrequest?on?|?off;
默認(rèn)值是 off ,查了半天也沒(méi)查到怎么發(fā)子請(qǐng)求,使用 addition、auth_request 之類的文檔中寫(xiě)著可以發(fā)子請(qǐng)求的模塊測(cè)試也沒(méi)效果。網(wǎng)上搜的很多是自己寫(xiě)模塊或者使用一些第三方模塊,有了解的小伙伴可以留言哈,這個(gè)咱們就先不測(cè)試了。
merge_slashes
開(kāi)啟或者關(guān)閉將請(qǐng)求 URI 中相鄰兩個(gè)或更多斜線合并成一個(gè)的功能。
merge_slashes?on?|?off;
默認(rèn)值是 on ,比如說(shuō)我們經(jīng)??赡茉谳斎?URL 的時(shí)候多打了一個(gè)斜杠,比如 /slashes/aaa.html 打成了 //slashes/aaa.html 。這種情況下,如果 merge_slashes 的配置是 off 的話,那么對(duì)于?location /slashes/
這個(gè)配置就無(wú)法匹配成功了。查看日志,會(huì)報(bào)出這樣的錯(cuò)誤。
2022/08/07?22:26:19?[error]?1611#0:?*87?open()?"/usr/local/nginx/html//slashes/aaa.html"?failed?(2:?No?such?file?or?directory),?client:?192.168.56.1,?server:?core.nginx.test,?request:?"GET?//slashes/aaa.html?HTTP/1.1",?host:?"192.168.56.88"
也就是說(shuō),訪問(wèn)的 URI 按照普通的路徑?/usr/local/nginx/html//slashes/aaa.html
?來(lái)進(jìn)行訪問(wèn)了。在 Linux 中,這種訪問(wèn)方式也是不被允許的。
[root@localhost?html]#?ll?/usr/local/nginx/html//slashes/aaa.html
ls:?cannot?access?'/usr/local/nginx/html//slashes/aaa.html':?No?such?file?or?directory
另外還需要注意的是,如果URI中包含 base64 編碼的內(nèi)容,必須將斜線壓縮調(diào)整成 off ,因?yàn)?base64 編碼本身會(huì)使用 “/” 字符。出于安全方面的考慮,最好還是不要關(guān)閉壓縮。這條指令可以指定在默認(rèn)虛擬主機(jī)的 server 配置級(jí)別。這樣的話,這個(gè)配置可以覆蓋監(jiān)聽(tīng)同一地址和端口的所有虛擬主機(jī)。
msie_padding
msie_padding?on?|?off;
默認(rèn) on ,在響應(yīng)狀態(tài)碼大于等于 400 時(shí),在響應(yīng)正文中添加一段注釋,使響應(yīng)正文達(dá)到512字節(jié)。本指令可以為 MSIE 客戶端開(kāi)啟或關(guān)閉這個(gè)功能。IE 相關(guān)的配置咱們就不試了,我這也沒(méi)有現(xiàn)成的 IE 瀏覽器。
msie_refresh
msie_refresh?on?|?off;
默認(rèn) off ,為 MSIE 客戶端開(kāi)啟或者關(guān)閉用頁(yè)面刷新取代頁(yè)面重定向的功能。IE 相關(guān)的配置咱們就不試了,我這也沒(méi)有現(xiàn)成的 IE 瀏覽器。
總結(jié)
是不是感覺(jué)大開(kāi)眼界了?平常我們以為多打兩個(gè)斜杠沒(méi)事,但其實(shí)是 Nginx 默認(rèn)幫我們處理了。響應(yīng)類型的概念相信也讓大家對(duì)瀏覽器如何處理響應(yīng)頭有了新的認(rèn)識(shí),原來(lái) Nginx 也是根據(jù)文件的后綴名來(lái)進(jìn)行判斷的。最后,還有一大堆配置指令等著我們呢,別急,下篇文章見(jiàn)。
參考文檔:
http://nginx.org/en/docs/http/ngx_http_core_module.html