原文連接:http://colobu.com/2015/10/26/nginx-limit-modules/?utm_source=tuicool&utm_medium=referralhtml
電商平臺營銷時候,常常會碰到的大流量問題,除了作流量分流處理,可能還要作用戶黑白名單、信譽分析,進而根據用戶ip信譽權重作相應的流量攔截、限制流量。
Nginx自身有的請求限制模塊ngx_http_limit_req_module、流量限制模塊ngx_stream_limit_conn_module基於令牌桶算法,能夠方便的控制令牌速率,自定義調節限流,實現基本的限流控制。前端
對於提供下載的網站,確定是要進行流量控制的,例如軟件下載站、視頻服務等。
它也能夠減小一些爬蟲程序或者DDOS的攻擊。nginx
對這兩個模塊的介紹的文章也很多,這裏轉載一篇hopestar的文章: nginx限制IP鏈接數的範例參考, 由於他介紹的很簡潔。git
如何Nginx限制同一個ip的鏈接數,限制併發數目:github
這個變量只能在http使用 :web
1
2
3
|
vi /export/servers/nginx/conf/nginx.conf
limit_zone one
$binary_remote_addr 20m;
limit_req_zone $binary_remote_addr zone=req_one:20m rate=12r/s;
|
這個變量能夠在http
, server
, location
使用 我是限制nginx上的全部服務,因此添加到http裏面 (若是你須要限制部分服務,可在nginx/conf/domains裏面選擇相應的server或者location添加上即可)算法
1
2
3
4
5
6
|
vi /export/servers/nginx/conf/nginx.conf
limit_zone one
$binary_remote_addr 20m;
limit_req_zone $binary_remote_addr zone=req_one:20m rate=12r/s;
limit_conn one 10;
limit_req zone=req_one burst=120;
|
參數詳解(數值按具體須要和服務器承載能力設置,):緩存
1
2
3
4
|
limit_zone,是針對每一個變量(這裏指
IP,即$binary_remote_addr)定義一個存儲session狀態的容器。這個示例中定義了一個20m的容器,按照32bytes/session,能夠處理640000個session。
limit_req_zone 與limit_zone相似。rate是請求頻率. 每秒容許
12個請求。
limit_conn one
10 : 表示一個IP能發起10個併發鏈接數
limit_req: 與limit_req_zone對應。burst表示緩存住的請求數。
|
範例:服務器
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
http
{
limit_zone one $binary_remote_addr 20m;
limit_req_zone $binary_remote_addr zone=req_one:20m rate=12r/s;
limit_conn one 10;
limit_req zone=req_one burst=120;
server {
listen 80;
server_name status.xxx.com ;
location / {
stub_status on;
access_log off;
}
}
}
|
1
|
/
export/servers/nginx/sbin/nginx -s reload
|
Nginx限制流量/限制帶寬 具體參考官方文檔session
以上配置會對全部的ip都進行限制,有些時候咱們不但願對搜索引擎的蜘蛛或者某些本身的代理機過來的請求進行限制, 對於特定的白名單ip咱們能夠藉助geo指令實現。
先在nginx的請求日誌進行統計,查看那個ip的訪問量比較大, 運行:
1
2
|
cat access.log | grep "03/Jun" |awk '{print $1}'|sort |uniq -c|sort -nrk 1|head -n 10
#列出訪問日誌裏面在
6月3號這天前10個訪問量最大的ip.
|
接下來就能夠對這些IP進行分析了。看哪些須要進行白名單設置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
http{
geo
$limited { # the variable created is $limited
default 1;
127.0.0.1/32 0;
10.12.212.63 0;
}
map
$limited $limit {
1 $binary_remote_addr;
0 "";
}
limit_zone one
$binary_remote_addr 20m;
limit_req_zone
$limit zone=req_one:20m rate=20r/s;
limit_conn one
10;
limit_req zone=req_one burst=
120;
}
|
上面兩個須要用到map和geo模塊,這是nginx自帶的模塊,有的運維喜歡把他們關閉,本身./sbin/nginx -V
留意一下。把配置的--whithout-XXX-module
去掉從新編譯一下就能夠了。 上面這段配置的意思是:
1.geo指令定義了一個白名單limitedlimited的值爲0
2.使用map指令映射搜索引擎客戶端的ip爲空串,若是不是搜索引擎就顯示自己真實的ip,這樣搜索引擎ip就不能存到limit_req_zone內存session中,因此不會限制搜索引擎的ip訪問
順帶一提,爲了獲取客戶端的真實IP。該模塊須要安裝read_ip模塊,運維應該默認有安裝。沒有的話也可自行安裝: 配置方式至關簡單,從新編譯 Nginx 加上 --with-http_realip_module 參數,如:
1
2
3
|
./configure --prefix=/opt/nginx --with-http_stub_status_module --with-pcre=../pcre-6.6 --with-http_realip_module
make
make install
|
在server中增長:
1
2
3
|
set_real_ip_from 192.168.1.0/24;
set_real_ip_from 192.168.2.1;
real_ip_header [X-Real-IP|X-Forwarded-For];
|
須要說明的地方就是設置IP源的時候能夠設置單個IP,也能夠設置IP段,另外是使用X-Real-IP仍是X-Forwarded-For,取決於前面的服務器有哪一個頭。
set_real_ip_from 設置的IP端可讓運維查看日誌,看下你的請求是來自哪些ip段。
從新加載一下服務,差很少就OK了。
再查看日誌的話,應該能夠看到客戶端的真實IP了。
注意:若是未安裝該模塊的話你的獲取到的IP端多是來自前端代理(如squid)的IP,結果就是多個用戶被當成單個用戶對待,致使應用不能響應。 參考:http://hi.baidu.com/thinkinginlamp/item/e2cf05263eb4d18e6e2cc3e6
再PS一下: 自測: 有條件的本身能夠用ab或者webben自測一下。
未安裝前壓測的話,由於有大量請求,因此access.log會有大量日誌,而error.log日誌沒有變化。
1
2
3
4
5
6
7
|
[root@qrwefsdf talk]# webbench -
c 30 -t 30 http://xxx.com
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://xxx.com
30 clients, running 30 sec.
Speed=193468 pages/min, 1254317 bytes/sec.
Requests: 96734 susceed, 0 failed.
|
安裝後會發現不少超出的請求會返回503,因此access.log日誌變化不快,error.log有大量記錄,提示limit_reque緩住了多少請求。
1
2
3
4
5
6
7
|
[root@qrwefsdf talk]# webbench -
c 30 -t 30 http://xxxx.com
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://xxx.com
30 clients, running 30 sec.
Speed=120 pages/min, 778 bytes/sec.
Requests: 60 susceed, 0 failed.
|