文章原創於公眾號:程式猿周先森。本平臺不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。
在當今流量徒增的網際網路時代,很多業務場景都會涉及到高併發。這個時候介面進行限流是非常有必要的,而限流是Nginx最有用的特性之一,而且也是最容易被錯誤配置的特性之一。本篇文章主要講講Nginx如何對介面進行限流。
Nginx限流主要分為兩種方式:
- 限制訪問頻率
- 限制併發連線數
為什麼需要限流?開源人員可以通過限流限制訪問速度來防止外部暴力掃描,或者減少密碼被暴力破解的可能性。也可以解決流量突發問題(如線上活動導致訪問量突增)。用一句話來概括就是說限流是用於保護伺服器不會因為承受不住同一時刻的大量併發請求而當機。接下來我們分別來看看Nginx的兩種限流方式:
限制訪問頻率限制訪問頻率其實需要分成兩種情況:正常情況下進行訪問頻率限制以及流量突發情況下進行訪問頻率限制。我們分別看看這兩種情況下Nginx是如何進行處理的:
正常流量限制訪問頻率Nginx中使用ngxhttplimitreqmodule模組來限制的訪問頻率,限制的原理實質是基於漏桶演算法原理來實現的。在nginx.conf配置檔案中可以使用limitreqzone命令及limit_req命令限制單個IP的請求處理頻率。
我們可以先來看看這兩個命令的語法結構:
- limitreqzone key zone rate
對於上面語法結構的引數簡單做下解釋:
- key: 定義需要限流的物件。
- zone: 定義共享記憶體區來儲存訪問資訊。
- rate: 用於設定最大訪問速率。
接下來我們看個簡單的例子:
突發流量限制訪問頻率上面的配置一定程度可以限制訪問頻率,但是也存在著一個問題:如果突發流量超出請求被拒絕處理,無法處理活動時候的突發流量,這時候應該如何進一步處理呢?Nginx提供burst引數結合nodelay引數可以解決流量突發的問題,可以設定能處理的超過設定的請求數外能額外處理的請求數。我們可以將之前的例子新增burst引數以及nodelay引數:
http {
limitreqzone $binaryremoteaddr zone=myLimit:10m rate=3r/s;
}
server {
location / {
limit_req zone=myLimit burst=5 nodelay;
rewrite / http://www.niyueling.cn permanent;
}
}
可以看到我在原有的location中的limit_req指令中新增了burst=5 nodelay,如果沒有新增nodelay引數,則可以理解為預先在記憶體中佔用了5個請求的位置,如果有5個突發請求就會按照200ms去依次處理請求,也就是1s內把5個請求全部處理完畢。如果1s內有新的請求到達也不會立即進行處理,因為緊急程度更低。這樣實際上就會將額外的5個突發請求以200ms/個去依次處理,保證了處理速率的穩定,所以在處理突發流量的時候也一樣可以正常處理。如果新增了nodelay引數則表示要立即處理這5個突發請求。
限制併發連線數Nginx中的ngxhttplimitconnmodule模組提供了限制併發連線數的功能,可以使用limitconnzone指令以及limit_conn執行進行配置。接下來我們可以通過一個簡單的例子來看下:
http {
limitconnzone $binaryremoteaddr zone=myip:10m;
limitconnzone $server_name zone=myServerName:10m;
}
server {
location / {
limit_conn myip 10;
limit_conn myServerName 100;
rewrite / http://www.niyueling.cn permanent;
}
}
上面配置了單個IP同時併發連線數最多隻能10個連線,並且設定了整個虛擬伺服器同時最大併發數最多隻能100個連結。當然,只有當請求的header被伺服器處理後,虛擬伺服器的連線數才會計數。剛才有提到過Nginx是基於漏桶演算法原理實現的,實際上限流一般都是基於漏桶演算法和令牌桶演算法實現的。接下來我們來看看兩個演算法的介紹:
漏桶演算法漏桶演算法是網路世界中流量整形或速率限制時經常使用的一種演算法,它的主要目的是控制資料注入到網路的速率,平滑網路上的突發流量。漏桶演算法提供了一種機制,通過它,突發流量可以被整形以便為網路提供一個穩定的流量。也就是我們剛才所講的情況。漏桶演算法提供的機制實際上就是剛才的案例:突發流量會進入到一個漏桶,漏桶會按照我們定義的速率依次處理請求,如果水流過大也就是突發流量過大就會直接溢位,則多餘的請求會被拒絕。所以漏桶演算法能控制資料的傳輸速率。
令牌桶演算法令牌桶演算法是網路流量整形和速率限制中最常使用的一種演算法。典型情況下,令牌桶演算法用來控制傳送到網路上的資料的數目,並允許突發資料的傳送。Google開源專案Guava中的RateLimiter使用的就是令牌桶控制演算法。令牌桶演算法的機制如下:存在一個大小固定的令牌桶,會以恆定的速率源源不斷產生令牌。如果令牌消耗速率小於生產令牌的速度,令牌就會一直產生直至裝滿整個令牌桶。
漏桶演算法與令牌桶演算法的區別兩種演算法都能夠限制資料傳輸速率,但令牌桶還允許某種程度的突發傳輸。因為令牌桶演算法只要令牌桶中存在令牌,那麼就可以突發的傳輸對應的資料到目的地,所以更適合流量突發的情形下進行使用。
如果喜歡我的文章,歡迎關注我的個人公眾號