Nginx防止大流量攻擊,限制流量訪問(limit_req_zone模組)以及進行網站壓力測試
文章目錄
一、限流的幾種演算法
(一)、計數器演算法
採用計數器實現限流有點簡單粗暴,一般我們會限制一秒鐘之內能夠通過的請求數,比如限流 qps(每秒查詢率)為100,演算法的實現思路就是從第一個請求進來開始計時,在接下去的1s內,每來一個請求,就把計數加1,如果累加的數字達到了100,那麼後續的請求就會被全部拒絕。等到1s結束後,把計數恢復成0,重新開始計數。
(二)、漏桶演算法
為了消除"突刺現象",可以採用漏桶演算法實現限流,漏桶演算法這個名字就很形象,演算法內部有一個容器,類似生活用到的漏斗,當請求進來時,相當於水倒入漏斗,然後從下端小口慢慢勻速的流出。不管上面流量多大,下面流出的速度始終保持不變。
不管服務呼叫方多麼不穩定,通過漏桶演算法進行限流,每10毫秒處理一次請求。因為處理的速度是固定的,請求進來的速度是未知的,可能突然進來很多請求,沒來得及處理的請求就先放在桶裡,既然是個桶,肯定是有容量上限,如果桶滿了,那麼新進來的請求就丟棄。
簡單理解為:
- 水(請求)從上方倒入水桶,從水桶下方流出(被處理);
- 來不及流出的水存在水桶中(緩衝),以固定速率流出;
- 水桶滿後水溢位(丟棄)。
- 這個演算法的核心是:快取請求、勻速處理、多餘的請求直接丟棄。
- 相比漏桶演算法,令牌桶演算法不同之處在於它不但有一隻“桶”,還有個佇列,這個桶是用來存放令牌的,佇列才是用來存放請求的。
(三)、令牌桶演算法
從某種意義上講,令牌桶演算法是對漏桶演算法的一種改進,漏桶演算法能夠限制請求呼叫的速率,而令牌桶演算法能夠在限制呼叫的平均速率的同時還允許一定程度的突發呼叫。
在令牌桶演算法中,存在一個桶,用來存放固定數量的令牌。演算法中存在一種機制,以一定的速率往桶中放令牌。每次請求呼叫需要先獲取令牌,只有拿到令牌,才有機會繼續執行,否則就只能選擇等待可用的令牌、或者直接拒絕。
簡單理解為:
- 令牌以固定速率產生,並快取到令牌桶中;
- 令牌桶放滿時,多餘的令牌被丟棄;
- 請求要消耗等比例的令牌才能被處理;
- 令牌不夠時,請求被快取或者被拒絕
二、 limit_req_zone 引數配置
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
#限流模組配置
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
第一個引數:$binary_remote_addr 表示通過remote_addr這個標識來做限制,“binary_”的目的是縮寫記憶體佔用量,
是限制同一客戶端ip地址。
第二個引數:zone=one:10m 表示生成一個大小為10M,名字為one的記憶體區域,用來儲存訪問的頻次資訊。
第三個引數:rate=1r/s 表示允許相同標識的客戶端的訪問頻次,這裡限制的是每秒1次,還可以有比如30r/m的。
------------------------------------------------------------------------------------------------------
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
limit_req zone=one burst=3 nodelay;
limit_req_status 598;
root html;
index index.html index.htm;
}
第一個引數:zone=one 設定使用哪個配置區域來做限制,與上面limit_req_zone 裡的 one 對應。
第二個引數:burst=3,重點說明一下這個配置,burst爆發的意思,這個配置的意思是設定一個大小為3的緩衝區當有大量請
求(爆發)過來時,超過了訪問頻次限制的請求可以先放到這個緩衝區內。
第三個引數:nodelay,如果設定,超過訪問頻次而且緩衝區也滿了的時候就會直接返回503,如果沒有設定,則所有請求會等待排隊。
第四個引數:limit_req_status為自定義返回值,當流量被拒絕後返回598
三、limit_conn_module 引數配置
這個模組用來限制單個IP的請求數。並非所有的連線都被計數。只有在伺服器處理了請求並且已經讀取了整個請求頭時,連線才被計數。
limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
location /download/ {
limit_conn addr 1;
}
一次只允許每個IP地址一個連線。
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
...
limit_conn perip 10;
limit_conn perserver 100;
}
可以配置多個limit_conn指令。例如,以上配置將限制每個客戶端IP連線到伺服器的數量,同時限制連線到虛擬伺服器的總數。
limit_conn_zone $binary_remote_addr zone=addr:10m;
這裡,客戶端IP地址作為關鍵。請注意,不是$ remote_addr,而是使用$ binary_remote_addr變數。 $ remote_addr變數的大小可以從7到15個位元組不等。儲存的狀態在32位平臺上佔用32或64位元組的記憶體,在64位平臺上總是佔用64位元組。對於IPv4地址,$ binary_remote_addr變數的大小始終為4個位元組,對於IPv6地址則為16個位元組。儲存狀態在32位平臺上始終佔用32或64個位元組,在64位平臺上佔用64個位元組。一個兆位元組的區域可以保持大約32000個32位元組的狀態或大約16000個64位元組的狀態。如果區域儲存耗盡,伺服器會將錯誤返回給所有其他請求。
Syntax: limit_conn_log_level info | notice | warn | error;
Default:
limit_conn_log_level error; #當伺服器限制連線數時,設定所需的日誌記錄級別。
Context: http, server, location
Syntax: limit_conn_status code;
Default:
limit_conn_status 503; #設定拒絕請求的返回值。
Context: http, server, location
四、網站壓力測試
Webbench是一個在linux下使用的非常簡單的網站壓測工具。它使用fork()模擬多個客戶端同時訪問我們設定的URL,測試網站在壓力下工作的效能,最多可以模擬3萬個併發連線去測試網站的負載能力。
Apache ab(Apache Bench效能測試工具,這是apache免費自帶的效能測試工具,就在apache的bin目錄下,它能模擬多個併發請求,也就是說它主要是用來測試你的網站每秒能處理多少請求的。
1、安裝Webbench
yum install gcc make ctags -y
#安裝Webbench
wget https://www.moerats.com/usr/down/webbench-1.5.tar.gz
tar zxvf webbench-1.5.tar.gz
mkdir /use/local/man
cd man/
touch man1
cd ~/webbench-1.5
make && make install
2、使用 Webbench
#使用幫助
webbench -h
#測試命令,-c為併發數;-t為測試時長,單位秒;後面為連結
webbench -c 800 -t 20 http://www.baidu.com/
3、使用apache ab
需要提前安裝apache:
yum install -y httpd
#使用幫助
ab -h
#測試1,-n為傳送請求次數;-c併發數;後面為連結
ab -n 200 -c 100 http://www.baidu.com/
#測試2,-t為測試時長,單位秒;-c併發數;後面為連結
ab -t 70 -c 30 http://www.baidu.com/