NGINX 頻寬與連線數控制
對於負載量比較高的伺服器,可以設定每一位使用者可使用的資源上限,例如同時間最大連線數、連線頻率(每秒或每分鐘連線次數)以及下載速度。
同時間最大連線數
若要限制同時間最大連線數,首先要使用 limit_conn_zone 定義一個 key 與 zone 參數:
limit_conn_zone $binary_remote_addr zone=addr:10m;
這裡定義一個名為 addr 的 zone,空間大小是 10MB,worker 行程會使用這個 zone 所配置的共享記憶體空間來儲存 key 的計數值。這裡的我們使用 $binary_remote_addr 來作為判斷來源 IP 的依據(key),會使用這個二進位的變數來作為 key 是因為它跟一般的字串比起來,會比較省空間,如果 zone 所配置的共享記憶體空間用完了,那伺服器就會回傳 503(Service Temporarily Unavailable)的錯誤訊息。
接著再使用 limit_conn 指定一個 IP 同時間可以允許的最大連線數:
location /download/ {
limit_conn addr 1;
}
以上的設定只有對於來源 IP 做限制,如果要設定整台伺服器所有連線的上限值,可以這樣設定:
http {
limit_conn_zone $server_name zone=server:10m;
server {
limit_conn server 1000;
}
}
這樣就可以把伺服器同時能夠接受的連線數上限設定為 1000。
連線頻率
若要限制連線頻率,首先也是一樣要用 limit_req_zone 定義 key 與 zone 參數:
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
這裡除了定義 zone 的名稱與大小之外,還加上了一個 rate 指定連線頻率的上限,單位可以使用每秒的連線次數(r/s)或是每分鐘的連線次數(r/m),例如若要指定每分鐘不可超過 30 次連線,則設定為 30r/m。
然後在需要限制連線頻率的地方加上 limit_req 的設定:
location /search/ {
limit_req zone=one burst=5;
}
這裡的 zone 就指定成剛剛上面定義的 zone 名稱,如果使用者所發出的連線頻率超過上限時,多出來的連線會先被放在伺服器的佇列中,等候一小段時間之後再處理,維持整體的連線頻率不會超過設定的上限,而 burst 參數是設定這個佇列的長度,如果連線數多到連佇列都放不下時,就會產生 503 的錯誤。
如果不想讓放在佇列中的請求延遲處理,可以加上 nodelay:
limit_req zone=one burst=5 nodelay;
下載速度
若要限制每個連線的頻寬,可以使用 limit_rate:
location /download/ {
limit_rate 50k;
}
在這樣的設定之下,每一個連線的下載速度最高不可超過每秒 50KB,但一個使用者可以同時開啟多條連線,如果需要限制連線數,可再加上 limit_conn 的限制條件:
location /download/ {
limit_conn addr 1;
limit_rate 50k;
}
如果要讓使用者可以先下載一部份的資料,再進行連線頻寬的限制,可以使用 limit_rate_after:
limit_rate_after 500k; limit_rate 20k;
這樣的設定可以讓使用者先下載 500KB 的資料之後,再進行限速,這通常會用在線上影音串流的網站,先讓使用者快速下載影音檔的表頭,然後再以正常的速度傳送串流資料,確認使用者是以串流的形式觀看,而不是直接下載。
以下是一個實際應用的範例,這個設定可讓一般的網頁同時可以接受 5 條連線(一般的瀏覽器通常最多使用 3 條),而在下載 /download/ 之下的檔案時,一次只能下載一個檔案,1MB 以下的檔案不限速,超過 1MB 的檔案則限速每秒 50KB。
http {
limit_conn_zone $binary_remote_address zone=addr:10m
server {
root /www/data;
limit_conn addr 5;
location / {
}
location /download/ {
limit_conn addr 1;
limit_rate_after 1m;
limit_rate 50k;
}
}
}
參考資料:NGINX
繼續閱讀: 12