Nginx讀書筆記三—-資源分配
- 2020 年 5 月 4 日
- 筆記
- Nginx及Apache
1、記憶體及磁碟資源分配
1.1 在磁碟中存儲HTTP請求體
語法: client_body_in_file_only on|clean|off;
默認: client_body_in_file_only off;
配置塊: http、 server、 location
當值為非off時, 用戶請求中的HTTP包體一律存儲到磁碟文件中, 即使只有0位元組也會存儲為文件。
當請求結束時,如果配置為on,則這個文件不會被刪除(該配置一般用於調試、定位問題),但如果配置為clean,則會刪除該文件。
1.2 HTTP包體盡量寫入到一個記憶體buffer中
語法:client_body_in_single_buffer on|off;
默認:client_body_in_single_buffer off;
配置塊:http、server、location
用戶請求中的HTTP包體一律存儲到記憶體buffer中。當然,如果HTTP包體的大小超過了下面client_body_buffer_size設置的值,包體還是會寫入到磁碟文件中。
1.3 存儲HTTP頭部的記憶體buffer大小
語法:client_header_buffer_size size;
默認:client_header_buffer_size 1k;
配置塊:http、server
上面配置項定義了正常情況下Nginx接收用戶請求中HTTP header部分(包括HTTP行和HTTP頭部)時分配的記憶體buffer大小。有時,請求中的HTTP header部分可能會超過這個大小,這時large_client_header_buffers定義的buffer將會生效。
1.4 存儲超大HTTP頭部的記憶體buffer大小
語法:large_client_header_buffers number size;
默認:large_client_header_buffers 4 8k;
配置塊:http、server
large_client_header_buffers定義了Nginx接收一個超大HTTP頭部請求的buffer個數和每個buffer的大小。如果HTTP請求行(如GET/index HTTP/1.1)的大小超過上面的單個buffer,則返回”Request URI too large”(414)。請求中一般會有許多header,每一個header的大小也不能超過單個buffer的大小,否則會返回”Bad request
(400)。當然,請求行和請求頭部的總和也不可以超過 buffer個數 * buffer 大小。
1.5 存儲HTTP包體的記憶體buffer大小
語法:client_body_buffer_size size; 默認:client_body_buffer_size 8k/16k; 配置塊:http、server、location
上面配置項定義了Nginx接收HTTP包體的記憶體緩衝區大小。也就是說,HTTP包體會先接收到指定的這塊快取中,之後才決定是否寫入磁碟。
注意:如果用戶請求中含有HTTP頭部Content-Length,並且其標識的長度小於定義的buffer大小,那麼Nginx會自動降低本次請求所使用的記憶體buffer,以降低記憶體消耗。
client_max_body_size
語法: client_max_body_size size;
默認: client_max_body_size 1m;
配置塊: http, server, location
設置客戶端請求主體的最大允許大小,在「Content-Length」請求頭欄位中指定。如果請求中的大小超過了配置值,則將413(請求實體過大)錯誤返回給客戶端。請注意瀏覽器不能正確顯示此錯誤。將大小設置為0禁用客戶端請求主體大小的檢查。
瀏覽器在發送含有較大HTTP包體的請求時, 其頭部會有一個Content-Length欄位,client_max_body_size是用來限制Content-Length所示值的大小的。 因此, 這個限制包體的配置非常有用處, 因為不用等Nginx接收完所有的HTTP包體——這有可能消耗很長時間——就可以告訴用戶請求過大不被接受。例如, 用戶試圖上傳一個10GB的文件, Nginx在收完包頭後, 發現Content-Length超過client_max_body_size定義的值, 就直接發送413(“Request EntityToo Large”)響應給客戶端。
1.6 HTTP包體的臨時存放目錄
語法:client_body_temp_path dir-path[level1[level2[level3]]]
默認:client_body_temp_path client_body_temp;
配置塊:http、server、location
上面配置項定義HTTP包體存放的臨時目錄。在接收HTTP包體時,如果包體的大小大於client_body_buffer_size,則會以一個遞增的整數命名並存放到client_body_temp_path指定的目錄中。後面跟著的level1、level2、level3,是為了防止一個目錄下的文件數量太多,從而導致性能下降,因此使用了level參數,這樣可以按照臨時
件名最多再加三層目錄。例如:client_body_temp_pathoptnginx/client_temp 1 2;如果新上傳的HTTP包體使用00000123456作為臨時文件名,就會被存放在這個目錄中。optnginx/client_temp/6/45/00000123456
1.7 connection_pool_size
語法:connection_pool_size size; 默認: connection_pool_size 256; 配置塊: http、 server
Nginx對於每個建立成功的TCP連接會預先分配一個記憶體池,上面的size配置項將指定這個記憶體池的初始大小(即ngx_connection_t結構體中的pool記憶體池初始大小,),用於減少內核對於小塊記憶體的分配次數。需慎重設置,因為更大的size會使伺服器消耗的記憶體增多,而更小的size則會引
更多的記憶體分配次數。一般不設置
1.8 request_pool_size
語法:request_pool_size size;
默認:request_pool_size 4k;
配置塊:http、server
Nginx開始處理HTTP請求時,將會為每個請求都分配一個記憶體池,size配置項將指定這個記憶體池的初始大小(即ngx_http_request_t結構體中的pool記憶體池初始大小),用於減少內核對於小塊記憶體的分配次數。TCP連接關閉時會銷毀connection_pool_size指定的連接記憶體池,HTTP請求結束
會銷毀request_pool_size指定的HTTP請求記憶體池,但它們的創建、銷毀時間並不一致,因為一個TCP連接可能被複用於多個HTTP請求。
2、網路連接設置
2.1 讀取HTTP頭部的超時時間
語法:client_header_timeout time(默認單位:秒); 默認:client_header_timeout 60;
配置塊:http、server、location
客戶端與伺服器建立連接後將開始接收HTTP頭部,在這個過程中,如果在一個時間間隔(超時時間)內沒有讀取到客戶端發來的位元組,則認為超時,並向客戶端返回408( ” Request timed out ” )響應。
2.2 讀取HTTP包體的超時時間
語法:client_body_timeout time(默認單位:秒); 默認:client_body_timeout 60; 配置塊:http、server、location
此配置項與client_header_timeout相似,只是這個超時時間只在讀取HTTP包體時才有效。如果超時,同樣報408( ” Request timed out ” )響應
2.3 發送響應的超時時間
語法:send_timeout time; 默認:send_timeout 60; 配置塊:http、server、location
這個超時時間是發送響應的超時時間,即Nginx伺服器向客戶端發送了數據包,但客戶端一直沒有去接收這個數據包。如果某個連接超過send_timeout定義的超時時間,那麼Nginx將會關閉這個連接。
2.4 lingering_close
語法:lingering_close off|on|always;
默認:lingering_close on;
配置塊:http、server、location
該配置控制Nginx關閉用戶連接的方式。always表示關閉用戶連接前必須無條件地處理連接上所有用戶發送的數據。off表示關閉連接時完全不管連接上是否已經有準備就緒的來自用戶的數據。on是中間值,一般情況下在關閉連接前都會處理連接上的用戶發送的數據,除了有些情況下在業務上認定這之後的數據是不必要的。
2.5 lingering_time
語法:lingering_time time;
默認:lingering_time 30s;
配置塊:http、server、location
lingering_close啟用後,這個配置項對於上傳大文件很有用。上文講過,當用戶請求的 Content-Length大於max_client_body_size配置時,Nginx服務會立刻向用戶發送413(Requestentity too large)響應。
但是,很多客戶端可能不管413返回值,仍然持續不斷地上傳HTTP body,這時,經過了lingering_time設置的時間後,Nginx將不管用戶是否仍在上傳,都會把連接關閉掉。
2.6 lingering_timeout
語法:lingering_timeout time;
默認:lingering_timeout 5s;
配置塊:http、server、location
lingering_close生效後,在關閉連接前,會檢測是否有用戶發送的數據到達伺服器,如果超過lingering_timeout時間後還沒有數據可讀,就直接關閉連接;否則,必須在讀取完連接緩衝區上的數據並丟棄掉後才會關閉連接。
2.8 對某些瀏覽器禁用keepalive功能
語法:keepalive_disable[msie6|safari|none]...
默認:keepalive_disablemsie6 safari
配置塊:http、server、location
HTTP請求中的keepalive功能是為了讓多個請求復用一個HTTP長連接,這個功能對伺服器的性能提高是很有幫助的。但有些瀏覽器,如IE 6和Safari,它們對於使用keepalive功能的POST請求處理有功能性問題。因此,針對IE 6及其早期版本、Safari瀏覽器默認是禁用keepalive功能的。
2.9 keepalive超時時間
語法:keepalive_timeout time(默認單位:秒); 默認:keepalive_timeout 75; 配置塊:http、server、location
一個keepalive連接在閑置超過一定時間後(默認的是75秒),伺服器和瀏覽器都會去關閉這個連接。當然,keepalive_timeout配置項是用來約束Nginx伺服器的,Nginx也會按照規範把這個時間傳給瀏覽器,但每個瀏覽器對待keepalive的策略有可能是不同的。,MSIE關閉保持活動連接為60秒
2.10 一個keepalive長連接上允許承載的請求最大數
語法:keepalive_requests n; 默認:keepalive_requests 100; 配置塊:http、server、location
一個keepalive連接上默認最多只能發送100個請求。
2.11 tcp_nodelay
語法:tcp_nodelay on|off;
默認:tcp_nodelay on;
配置塊:http、server、location
確定對keepalive連接是否使用TCP_NODELAY選項。它在SSL連接上啟用,用於無緩衝的代理,以及用於WebSocket代理。
2.12 tcp_nopush
語法:tcp_nopush on|off;
默認:tcp_nopush off;
配置塊:http、server、location
在打開sendfile選項時,確定是否開啟FreeBSD系統上的TCP_NOPUSH或Linux系統上的TCP_CORK功能。打開tcp_nopush後,將會在發送響應時把整個響應包頭放到一個TCP包中發送。
3、對客戶端請求的限制
3.1 按HTTP方法名限制用戶請求
語法: limit_except method...{...}
配置塊: location
Nginx通過limit_except後面指定的方法名來限制用戶請求。 方法名可取值包括: GET、HEAD、 POST、 PUT、 DELETE、 MKCOL、 COPY、 MOVE、 OPTIONS、 PROPFIND、PROPPATCH、 LOCK、 UNLOCK或者PATCH。 例如:
limit_except GET { allow 192.168.1.0/32; deny all; }
注意, 允許GET方法就意味著也允許HEAD方法。 因此, 上面這段程式碼表示的是禁止GET方法和HEAD方法, 但其他HTTP方法是允許的。
3.2 對請求的限速
語法: limit_rate speed; 默認: limit_rate 0; 配置塊: http、 server、 location、 if
此配置是對客戶端請求限制每秒傳輸的位元組數。 speed可以使用多種單位, 默認參數為0, 表示不限速。針對不同的客戶端, 可以用$limit_rate參數執行不同的限速策略。 例如:
server { if ($slow) { set $limit_rate 4k; } }
3.3 limit_rate_after
語法: limit_rate_after time; 默認: limit_rate_after 1m; 配置塊: http、 server、 location、 if
此配置表示Nginx向客戶端發送的響應長度超過limit_rate_after後才開始限速。 例如:
limit_rate_after 1m;
limit_rate 100k;
4、文件操作的優化配置項
4.1 sendfile系統調用
語法: sendfile on|off;
默認: sendfile off;
配置塊: http、 server、 location
可以啟用Linux上的sendfile系統調用來發送文件, 它減少了內核態與用戶態之間的兩次記憶體複製, 這樣就會從磁碟中讀取文件後直接在內核態發送到網卡設備, 提高了發送文件的效率。
4.2 打開文件快取
語法: open_file_cache max=N[inactive=time]|off;
默認: open_file_cache off;
配置塊: http、 server、 location
文件快取會在記憶體中存儲以下3種資訊:
- 文件句柄、 文件大小和上次修改時間。
- 已經打開過的目錄結構。
- 沒有找到的或者沒有許可權操作的文件資訊。
這樣, 通過讀取快取就減少了對磁碟的操作。該配置項後面跟3種參數。
- max: 表示在記憶體中存儲元素的最大個數。 當達到最大限制數量後, 將採用LRU(Least Recently Used) 演算法從快取中淘汰最近最少使用的元素。
- inactive: 表示在inactive指定的時間段內沒有被訪問過的元素將會被淘汰。 默認時間為60秒。
- off: 關閉快取功能。
例如:
open_file_cache max=1000 inactive=20s;
4.3 是否快取打開文件錯誤的資訊
語法: open_file_cache_errors on|off;
默認: open_file_cache_errors off;
配置塊: http、 server、 location
此配置項表示是否在文件快取中快取打開文件時出現的找不到路徑、 沒有許可權等錯誤資訊。
4.4 不被淘汰的最小訪問次數
語法: open_file_cache_min_uses number; 默認: open_file_cache_min_uses 1; 配置塊: http、 server、 location
它與open_file_cache中的inactive參數配合使用。 如果在inactive指定的時間段內, 訪問次數超過了open_file_cache_min_uses指定的最小次數, 那麼將不會被淘汰出快取。
(8) 檢驗快取中元素有效性的頻率
語法: open_file_cache_valid time;
默認: open_file_cache_valid 60s;
配置塊: http、 server、 location
默認為每60秒檢查一次快取中的元素是否仍有效。
5、對客戶端請求的特殊處理
5.1 忽略不合法的HTTP頭部
語法: ignore_invalid_headers on|off;
默認: ignore_invalid_headers on;
配置塊: http、 server
如果將其設置為off, 那麼當出現不合法的HTTP頭部時, Nginx會拒絕服務, 並直接向用戶發送400(Bad Request) 錯誤。如果將其設置為on, 則會忽略此HTTP頭部。
5.2 HTTP頭部是否允許下劃線語法: underscores_in_headers on|off;
默認: underscores_in_headers off;
配置塊: http、 server
默認為off, 表示HTTP頭部的名稱中不允許帶「_」(下劃線) 。
5.3 對If-Modified-Since頭部的處理策略
語法: if_modified_since[off|exact|before];
默認: if_modified_since exact;
配置塊: http、 server、 location
出於性能考慮, Web瀏覽器一般會在客戶端本地快取一些文件, 並存儲當時獲取的時間。 這樣, 下次向Web伺服器獲取快取過的資源時, 就可以用If-Modified-Since頭部把上次獲取的時間捎帶上, 而if_modified_since將根據後面的參數決定如何處理If-Modified-Since頭部。
相關參數說明如下。
- off: 表示忽略用戶請求中的If-Modified-Since頭部。 這時, 如果獲取一個文件, 那麼會正常地返迴文件內容。 HTTP響應碼通常是200。
- exact: 將If-Modified-Since頭部包含的時間與將要返回的文件上次修改的時間做精確比較, 如果沒有匹配上, 則返回200和文件的實際內容, 如果匹配上, 則表示瀏覽器快取的文件內容已經是最新的了, 沒有必要再返迴文件從而浪費時間與頻寬了, 這時會返回304 Not Modified, 瀏覽器收到後會直接讀取自己的本地快取。
- before: 是比exact更寬鬆的比較。 只要文件的上次修改時間等於或者早於用戶請求中的If-Modified-Since頭部的時間, 就會向客戶端返回304 Not Modified。
5.4 返回錯誤頁面時是否在Server中註明Nginx版本
語法: server_tokens on|off;
默認: server_tokens on;
配置塊: http、 server、 location
表示處理請求出錯時是否在響應的Server頭部中標明Nginx版本, 這是為了方便定位問題