相關文章:
《高可用服務設計之二:Rate limiting 限流與降級》
《nginx限制請求之一:(ngx_http_limit_conn_module)模塊》
《nginx限制請求之二:(ngx_http_limit_req_module)模塊》
《nginx限制請求之三:Nginx+Lua+Redis 對請求進行限制》
對應nginx接入層限流可以使用Nginx自帶的兩個模塊:
- 連接數限流模塊ngx_http_limit_conn_module:
- 漏桶算法實現的請求限流模塊ngx_http_limit_req_module
ngx_http_limit_conn_module 對於一些服務器流量異常、負載過大,甚至是大流量的惡意攻擊訪問等,進行並發數的限制;該模塊可以根據定義的鍵來限制每個鍵值的連接數,只有那些正在被處理的請求(這些請求的頭信息已被完全讀入)所在的連接才會被計數。
該模塊提供了兩個配置參數,limit_conn_zone 和 limit_conn ,
其中 limit_conn_zone 只能配置在 http{} 段,而 limit_conn 則可以配置於http{},server{},location{} 區段中。
三方模塊編譯安裝參數:
一、 limit_conn_zone
語法:limit_conn_zone $variable zone=name:size;
配置段:http
參數說明:
- $variable:定義鍵,要限流的維度;
- zone=name: 定義區域名稱(名稱隨意起名),主要作用與后面的 limit_conn中對應就好。
- size: 定義各個鍵共享內存空間大小。
該指令描述會話狀態存儲區域。鍵的狀態中保存了當前連接數,鍵的值可以是特定變量的任何非空值(空值不會被考慮)。
如:
#限制連接數 limit_conn_zone $binary_remote_addr zone=showjoy_conn:20m;
注釋:
客戶端的IP地址作為鍵。注意,這里使用的是 binary_remote_addr 變量,而不是 remote_addr 變量。
remote_addr變量的長度為7字節到15字節,而存儲狀態在32位平台中占用32字節或64字節,在64位平台中占用64字節。
binary_remote_addr變量的長度是固定的4字節,存儲狀態在32位平台中占用32字節或64字節,在64位平台中占用64字節。
1M共享空間可以保存3.2萬個32位的狀態,1.6萬個64位的狀態。
如果共享內存空間被耗盡,服務器將會對后續所有的請求返回 503 (Service Temporarily Unavailable) 錯誤。
二、limit_conn
語法:limit_conn zone_name number
配置段:http,server,location
參數說明:
- zone_name是上面limit_conn_zone中的zone定義的;
- number:是並發連接數量;
該指令指定每個給定鍵值的最大同時連接數,當超過這個數字時返回503(Service )錯誤。limit_conn是對某個key對應的總的網絡連接數進行限流。可以按照IP來限制IP維度的總連接數,或者按照服務域名來限制某個域名的總的連接數。(只有那些被nginx處理的且已經讀取了整個請求頭的請求連接才會被計數器統計)。
如(同一IP同一時間只允許有20個連接):
三、配置使用示例
limit_conn_zone $binary_remote_addr zone=showjoy_conn:20m;
主要用來定義變量、zone名稱、共享內存大小
limit_conn showjoy_conn 20;
將前面定義的showjoy_conn進行配置,並且限制同一IP並發連接數為20
配置方法如下:
1、在nginx.conf里的http{}里加上如下代碼:
2、在需要限制並發數和下載帶寬的網站配置server{}里加上如下代碼:
補充說明下參數:
- $binary_remote_addr是限制同一客戶端ip地址;
- $server_name是限制同一server最大並發數;
- limit_conn為限制並發連接數;
- limit_rate為限制下載速度;
注意:
nginx 1.1.8 之后的版本的語法改為limit_conn_zone $binary_remote_addr zone=NAME:10m;
NAME 就是 zone 的名字詳情請看這里 http://nginx.org/en/docs/http/ngx_http_limit_conn_module.html
限制連接數:
要限制連接,必須先有一個容器對連接進行計數,在http段加入如下代碼:
"zone=" 給它一個名字,可以隨便叫,這個名字要跟下面的 limit_conn 一致
$binary_remote_addr = 用二進制來儲存客戶端的地址,1m 可以儲存 32000 個並發會話
... 省掉 N 字
http
{
limit_conn_zone $binary_remote_addr zone=addr:10m;
接下來需要對server不同的位置(location段)進行限速,比如限制每個IP並發連接數為1,則
server
{
listen 80;
server_name 192.168.11.128;
index index.html index.htm index.php;
limit_conn addr 1; #是限制每個IP只能發起1個連接 (addr 要跟 limit_conn_zone 的變量對應)
limit_rate 100k; #限速為 100KB/秒
root html;
注意事項:
limit_rate 100k; //是對每個連接限速100k。這里是對連接限速,而不是對IP限速!如果一個IP允許兩個並發連接,那么這個IP就是限速limit_rate *
四、使用注意事項
事務都具有兩面性的。ngx_http_limit_conn_module 模塊雖說可以解決當前面臨的並發問題,但是會引入另外一些問題的。如前端如果有做LVS或反代,而我們后端啟用了該模塊功能,那不是非常多503錯誤了?這樣的話,可以在前端啟用該模塊,要么就是設置白名單。
模塊地址:https://yunpan.cn/cqSKP6BrJ2AeT 訪問密碼 4f50