技術積澱---nginx限速

Nginx 限速使用的是漏桶算法,此算法圖示如下,一個桶有一定的容量,水從桶的上方流入,如果桶中有水,水就會從下方按照一定的速率流出。

當然如果桶的容量已滿,流入的部分水就會溢出。如果桶沒有滿,水流入速度大於流出速度,那麼桶的容量就會上升。

類比nginx環境,設置限速是1秒100個請求。Nginx時間粒度是毫秒,也就是10ms允許通過1個請求。那麼可以認為桶的容量(10ms)是1。如果10ms到達2個請求,那麼1個請求可以通過,1個會被拒絕。如果10毫秒到達1個請求,那麼都可以順利的通過。這是非常簡單的場景,實際上漏桶算法也會考慮burst突發的場景。

漏桶算法桶的容量需要包括rate和burst部分。rate表示流出速率,burst表示突發情況下,允許的最大隊列。

漏桶算法算法常被用作(Traffic Shaping)或速率限制(Rate Limiting)。


技術積澱---nginx限速

如何配置最基本的限速?

配置Nginx 配置限速主要需要兩個指令limit_req_zone 用來配置限速,limit_req用來使用限速

技術積澱---nginx限速

limit_req_zone一般被配置在http作用域,需要三個參數:

Key 用來設置一次請求的key,比如上圖,設置的是用戶二進制IP。

Zone 設置一個共享的區域。用來保存每個特定的IP狀態,以及此IP訪問被限速的url頻次等。Zone等號後面是共享區域的名字。名字後面的冒號表示共享區域的大小。1M空間可以保存16000個IP信息,本例子可以大約保存1.6W個IP信息。

如果此空間被耗盡,nginx嘗試去移除老的記錄,但是如果空間仍然不夠用的話,NGINX會返回503 (Service Temporarily Unavailable)。

Rate 設置允許的最大請求速率。再次強調Nginx時間粒度是毫秒,對於本例子也就是100毫秒,只允許通過一個請求。

Nginx如何處理突發?

如果我們在100毫秒內收到兩個請求呢?對於第二個請求,NGINX將狀態碼503返回給客戶端。這可能不是我們想要的,因為應用程序在本質上往往是突發的。,我們更希望能緩衝多餘的請求,儘可能及時處理。NGINX可以通過limit_req指令的burst參數覆蓋這種場景:

技術積澱---nginx限速

burst參數設置,如果請求超過限速設置後,系統仍然可以接受多少請求,而不是直接拒絕。如上圖,桶的容量相當於21.如果100ms之內一個特定的IP地址,到來21個請求。Nginx會立即將一個請求送到upstream處理。剩下的20個請求就會入burst隊列,此隊列按照先進先出的方式消費。緊接著100ms,nginx直接從隊列的取出一個請求,進行消費。如果請求超過了burst隊列容量,請求依然會被拒絕。

Nginx 處理觸發 NoDelay。

limit_req配置burst參數後,一定程度上支持突發的流量。但是根據上面的介紹大家也看到了,其實消費速度還是100ms一個,只是先進了一個burst隊列。

另一種場景,假設被入隊的20個請求,第20個被處理的時候已經是2s之後了。而這20個請求是有關聯的。那麼第20個請求返回給用戶的時候,可能用戶已經不在需要了。

針對這種場景nginx提供了一個額外參數nodelay

技術積澱---nginx限速

使用nodelay參數,當一個burst請求到達時,只要隊列中有slot,nginx會立即轉發,但是它將這個slot標記為“已佔用”,直到適當的時間過去(在我們的示例中,在100毫秒之後)才釋放它供另一個請求使用。

假設隊列20 slot是空的,並且有21個請求同時從給定的IP地址到達。NGINX立即轉發所有21個請求,並標記隊列中的20個slot,然後每100毫秒釋放一個slot。(如果有25個請求,NGINX會立即轉發其中21個,標記20個slot,拒絕剩下的4個請求)。

現在假設新的100ms內,又有20個請求同時到達。但是隊列中只有一個slot被釋放,因此NGINX轉發一個請求,並拒絕其他19個請求。

我們可以看到加了nodelay參數後,在突發的情況下QPS會短暫超過設置的rate。但是從平均水平看,依舊是1秒10個。

注意:對於大多數部署,nginx建議在limit_req指令中包含burst和nodelay參數。

如何改變限速返回值?

默認情況下,當客戶端超過其速率限制時,NGINX返回503(Service Temporarily Unavailable)。使用limit_req_status指令設置不同的狀態碼(本例中為444):

技術積澱---nginx限速


如何調整超限日誌級別?

超限後的日誌默認是error,用戶可以通過limit_req_log_level

,指令調整日誌級別。

技術積澱---nginx限速

參考

https://blog.csdn.net/tjcyjd/article/details/77916146

https://www.nginx.com/blog/rate-limiting-nginx/

https://www.cnblogs.com/SUNSHINEC/p/9577682.html


分享到:


相關文章: