Nginx 對訪問量的控制

lufeijun1234發表於2018-12-27

瞭解 Nginx 的 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模組,對請求訪問量進行控制。

nginx 的內部結構是由核心模組和一系列的功能模組所組成。模組化架構使得每個模組的功能相對簡單,實現高內聚,同時也便於對 Nginx 進行功能擴充套件。
針對 web 請求,Nginx 所有開啟的模組會組成一條鏈,類似於闖關遊戲中的一道道關卡,每個模組負責特定的功能,例如實現壓縮的 ngx_http_gzip_module 模組,實現驗證的 ngx_http_auth_basic_module 模組和實現代理的 ngx_http_proxy_module 模組等。連線到伺服器的請求,會依次經過Nginx各個模組的處理,只有透過這些模組處理之後的請求才會真正的傳遞給後臺程式程式碼進行處理。

對於 web 伺服器而言,當遇到網路爬蟲,或者惡意大流量攻擊訪問時,會造成伺服器記憶體和 CPU 爆滿,頻寬也會跑滿,所以作為成熟的伺服器代理軟體,需要可以對這些情況進行控制。
Nginx 控制併發的方法有兩種,一種是透過IP或者其他引數控制其併發量;另外一種是控制單位時間內總的請求處理量。即對併發和並行的控制,這兩個功能分別由 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模組負責實現。

說明

該模組主要用於對請求併發量進行控制。

引數配置

  • limit_conn_zone

    指令配置 limit_conn_zone key zone=name:size
    配置的上下文:http
    說明:key 是 Nginx 中的變數,通常為 $binary_remote_addr | $server_name;name 為共享記憶體的名稱,size 為該共享記憶體的大小;此配置會申請一塊共享記憶體空間 name,並且儲存 key 的訪問情況

  • limit_conn_log_level

    語法:limit_conn_log_level info|notice|warn|error
    預設值:error
    配置上下文:http,server,location
    說明:當訪問達到最大限制之後,會將訪問情況記錄在日誌中

  • limit_conn

    語法:limit_conn zone_name number
    配置上下文:http,server,location
    說明:使用 zone_name 進行訪問併發控制,當超過 number 時返回對應的錯誤碼

  • limit_conn_status

    語法:limit_conn_status code
    預設值:503
    配置上下文:http,server,location
    說明:當訪問超過限制 number 時,給客戶端返回的錯誤碼,此錯誤碼可以配合 error_page 等引數,在訪問超量時給客戶返回友好的錯誤頁面

  • limit_rate

    語法:limit_rate rate
    預設值:0
    配置上下文:http,server,location
    說明:對每個連結的速率進行限制,rate 表示每秒的下載速度;

  • limit_rate_after

    語法:limit_rate_after size
    配置上下文:http,server,location
    說明:此命令和 limit_rate 配合,當流量超過 size 之後,limit_rate 才開始生效

簡單配置示例

limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
    listen       80;
    server_name  www.domain.com;
    root   /path/;
    index  index.html index.htm;
    location /ip {
      limit_conn_status 503; # 超限制後返回的狀態碼;
      limit_conn_log_level warn; # 日誌記錄級別
      limit_rate 50; # 頻寬限制
      limit_conn addr 1; # 控制併發訪問
    }
    # 當超過併發訪問限制時,返回503錯誤頁面
    error_page 503  /503.html;
}

說明

該模組主要控制單位時間內的請求數。使用 “leaky bucket” (漏斗)演算法進行過濾,在設定好限制 rate 之後,當單位時間內請求數超過 rate 時,模組會檢測 burst 值,如果值為0,則請求會依據 delay|nodelay 配置返回錯誤或者進行等待;如果 burst 大於0時,當請求數大於 rate 但小於 burst 時,請求進入等待佇列進行處理。

引數配置

  • limit_req_zone

    語法:limit_req_zone key zone=name:size rate=rate
    配置上下文:http
    說明:key 是 Nginx 中的變數,通常為 $binary_remote_addr | $server_name;name 為共享記憶體的名稱,size 為該共享記憶體的大小;rate 為訪問頻率,單位為 r/s 、r/m 。此配置會申請一塊共享記憶體空間 name,並且儲存 $key 的訪問情況;

  • limit_req

    語法: limit_rate zone=name [burst=number] [nodelay|delay=number]
    配置上下文:http,server,location
    說明:開啟限制,burst設定最多容量,nodelay決定當請求超量是,是等待處理還是返回錯誤碼;

  • limit_req_log_level 和 limit_req_status 配置引數左右與ngx_http_limit_conn_module模組一致;

簡單配置示例

limit_req_zone $binary_remote_addr zone=req:10m rate=2r/m;
server {
    listen       80;
    server_name  www.domain.com;
    root   /path/;
    index  index.html index.htm;
    location /limit {
      limit_req zone=req burst=3 nodelay;
    }
    # 當超過併發訪問限制時,返回503錯誤頁面
    error_page 503  /503.html;
}

這兩種訪問控制都需要申請記憶體空間,既然有記憶體空間,當然會存在記憶體耗盡的情況,這時新的請求都會被返回錯誤,所以當開啟訪問量限制時,需要透過監控防止此類情況發生。

透過對 Nginx 模組化架構的簡單介紹,重點了解 ngx_http_limit_conn_module 和 ngx_http_limit_req_module 模組的功能和配置引數,實現 Nginx 對請求的併發控制。如有不對,還請指教

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章