1. 程式人生 > 其它 >Nginx-12 實戰

Nginx-12 實戰

技術標籤:伺服器、運維nginx

Nginx-12 實戰

************ 如有侵權請提示刪除 ***************

  1. 例項一 限制訪問速率
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit;
    }
}

上述規則限制了每個IP訪問的速度為2r/s,並將該規則作用於根目錄。如果單個IP在非常短的時間內併發傳送多個請求,結果會怎樣呢?

  1. 例項二 burst快取處理
    我們看到,我們短時間內傳送了大量請求,Nginx按照毫秒級精度統計,超出限制的請求直接拒絕。這在實際場景中未免過於苛刻,真實網路環境中請求到來不是勻速的,很可能有請求“突發”的情況,也就是“一股子一股子”的。Nginx考慮到了這種情況,可以通過burst關鍵字開啟對突發請求的快取處理,而不是直接拒絕。
    來看我們的配置:
limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit burst=4;
    }
}

我們加入了burst=4,意思是每個key(此處是每個IP)最多允許4個突發請求的到來。如果單個IP在10ms內傳送6個請求,結果會怎樣呢?
相比例項一成功數增加了4個,這個我們設定的burst數目是一致的。具體處理流程是:1個請求被立即處理,4個請求被放到burst佇列裡,另外一個請求被拒絕。通過burst引數,我們使得Nginx限流具備了快取處理突發流量的能力。

但是請注意:burst的作用是讓多餘的請求可以先放到佇列裡,慢慢處理。如果不加nodelay引數,佇列裡的請求不會立即處理,而是按照rate設定的速度,以毫秒級精確的速度慢慢處理。

  1. 例項三 nodelay降低排隊時間
    例項二中我們看到,通過設定burst引數,我們可以允許Nginx快取處理一定程度的突發,多餘的請求可以先放到佇列裡,慢慢處理,這起到了平滑流量的作用。但是如果佇列設定的比較大,請求排隊的時間就會比較長,使用者角度看來就是RT變長了,這對使用者很不友好。有什麼解決辦法呢?nodelay引數允許請求在排隊的時候就立即被處理,也就是說只要請求能夠進入burst佇列,就會立即被後臺worker處理,請注意,這意味著burst設定了nodelay時,系統瞬間的QPS可能會超過rate設定的閾值。nodelay引數要跟burst一起使用才有作用。

延續例項二的配置,我們加入nodelay選項:

limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;
server { 
    location / { 
        limit_req zone=mylimit burst=4 nodelay;
    }
}
  1. 例項四 全站HTTP 跳轉HTTPS協議
    以http://www.a.com為例,要求全部訪問該頁面的請求全部跳轉到https://www.a.com/,且請求的URI和引數$query_string要保留。
  • 方案一:使用if進行判斷------最差
    這種情況下,多為把http和https寫在同一個server中,配置如下:
server {
    listen                            80 default_server;
    listen                            443 ssl default_server;
    server_name                 www.a.com a.com *.a.com;
    #證書
    ssl_certificate                "/data/nginx/ssl/nginx.crt";
    ssl_certificate_key          "/data/nginx/ssl/nginx.key";
    root                               /data/nginx/a;
    charset                         utf-8;
    if( $scheme = http){
          rewrite   ^/(.*)$  https://www.a.com$1 permanent;
    }
}

配置看著簡潔,效能最差,每次訪問都判斷,生產上不建議使用,能少用if儘量不用

  • rewrite 方法-----差
server{
    listen                            80 default_server;
     server_name                www.a.com a.com *.a.com;
     #多了這個
     rewrite   ^/(.*)$  https://www.a.com$1 permanent;
}
server {
    listen                            443 ssl default_server;
    server_name                 www.a.com a.com *.a.com;
    ssl_certificate                "/data/nginx/ssl/nginx.crt";
    ssl_certificate_key          "/data/nginx/ssl/nginx.key";
    root                               /data/nginx/a;
    charset                         utf-8;
}
  • rewrite 方法2-----好一些
    不用正則表示式,而用變數來提升效能
server{
    listen                            80 default_server;
     server_name               www.a.com a.com *.a.com;
     #多了這個
     rewrite   ^  https://www.a.com$request_uri? permanent;
}
server {
    listen                            443 ssl default_server;
    server_name                 www.a.com a.com *.a.com;
    ssl_certificate                "/data/nginx/ssl/nginx.crt";
    ssl_certificate_key          "/data/nginx/ssl/nginx.key";
    root                               /data/nginx/a;
    charset                         utf-8;
}

注意:#request_uri 已經包含了查詢引數,所以要在其重寫規則後面加上? ,以禁止再次傳遞引數,這種方法避免了 Nginx 內部處理正則的效能損壞,先比上一方法好很多

  • 採用return ----最好
    直接return ,避免正則和重寫
server{
    listen                            80 default_server;
     server_name               www.a.com a.com *.a.com;
     #換了這個
     return       301  https://¥host$request_uri;
}
server {
    listen                            443 ssl default_server;
    server_name                 www.a.com a.com *.a.com;
    ssl_certificate                "/data/nginx/ssl/nginx.crt";
    ssl_certificate_key          "/data/nginx/ssl/nginx.key";
    root                               /data/nginx/a;
    charset                         utf-8;
}

參考:nginx系列之七:限流配置_王道長的技術部落格-CSDN部落格_nginx限流配置