天天看點

接入層限流之ngx_http_limit_conn_module

【轉載請注明出處】: https://developer.aliyun.com/article/759766

ngx_http_limit_conn_module是Nginx提供的連接配接數限流子產品,是對某個KEY對應的總的網絡連接配接數進行限流。可以按照IP來限制IP次元的總連接配接數,或者按照服務域名來限制某個域名的總連接配接數。但不是每一個請求連接配接都會被計數器統計,隻有那些被Nginx處理的且已經讀取了整個請求頭的請求連接配接才會被計數器統計。

配置示例:

http {
    limit_conn_zone $binary_remote_addr zone=addr:10m; 
    limit_conn_log_level error; 
    limit_conn_status 503;
    ...
    server {
    ...
    location /limit {
        limit_conn addr 1;
    }           
  • limit_conn:要配置存放KEY和計數器的共享記憶體區域和指定KEY的最大連接配接數;此處指定的最大連接配接數是1,表示Nginx最多同時并發處理1個連接配接;
  • limit_conn_zone:用來配置限流KEY、及存放KEY對應資訊的共享記憶體區域大小;此處的KEY是

    $binary_remote_addr

    ,其表示IP位址,也可以使用如

    $server_name

    作為KEY來限制域名級别的最大連接配接數;

    文法是

    limit_conn_zone $variable zone=name:size;

$variable

定義鍵,zone=name定義區域名稱,size定義各個鍵共享記憶體空間大小。

$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_status:配置被限流後傳回的狀态碼,預設傳回503;
  • limit_conn_log_level:配置記錄被限流後的日志級别,預設error級别。

    具體可以參考官方文檔說明

    ngx_http_limit_conn_module

limit_conn的主要執行過程如下:

  1. 請求進入後首先判斷目前limit_conn_zone中相應KEY的連接配接數是否超出了配置的最大連接配接數;
  2. 如果超過了配置的最大值,則被限流,傳回limit_conn_status定義的錯誤狀态碼;否則相應KEY的連接配接數加1,并注冊請求處理完成的回調函數;
  3. 進行請求處理;
  4. 在結束請求階段會調用注冊的回調函數對相應KEY的連接配接數減1。

limt_conn可以限流某個KEY的總并發/請求數,KEY可以根據需要變化。

按照IP限制并發連接配接數

nginx配置

limit_conn_zone $binary_remote_addr zone=perip:10m; 
limit_conn_log_level info; 
limit_conn_status 503;

server {
    listen       8000;
    server_name  localhost;

    location /limit {
       limit_conn perip 2;
     #  add_header Content-Type "text/plain;charset=utf-8";
     #  return 200 "Your IP:$remote_addr";
       proxy_pass http://127.0.0.1:8081; 
    }

}           

允許每個IP最大并發連接配接數為2。

使用AB測試工具進行測試,并發數為5個,總的請求數為30個:

ab -n 30 -c 5 http://127.0.0.1:8000/limit/test           

檢視nginx access.log:

按照域名限制并發連接配接數

limit_conn_zone $server_name  zone=perserver:10m; 
limit_conn_log_level info; 
limit_conn_status 503;

server {
    listen       8000;
    server_name  localhost;

    location /limit {
       limit_conn perserver 3; 
       proxy_pass http://127.0.0.1:8081; 
    }

}           

access.log:

當多個 limit_conn 指令被配置時,所有的連接配接數限制都會生效。比如,下面配置不僅會限制單一IP來源的連接配接數,同時也會限制單一伺服器的總連接配接數:

limit_conn_zone $binary_remote_addr zone=perip:10m; 
limit_conn_zone $server_name zone=perserver:10m; 
limit_conn_log_level info; 
limit_conn_status 503;

server {
    listen       8000;
    server_name  localhost;

    location /limit {
       limit_conn perip 2;
       limit_conn perserver 3;
       proxy_pass http://127.0.0.1:8081; 
    }

}ss           

ngx_http_limit_conn_module 子產品雖說可以解決目前面臨的并發問題,但是會引入另外一些問題的。前端如果有做LVS或反代,而後端啟用了該子產品功能,那就會有很多的503錯誤,這樣的話,可以在前端啟用該子產品,要麼就是設定白名單。

繼續閱讀