Nginx使用limit_req_zone對同一IP訪問進行限流的方法
nginx可以使用ngx_http_limit_req_module模組的limit_req_zone指令進行限流訪問,防止使用者惡意攻擊刷爆伺服器。ngx_http_limit_req_module模組是nginx預設安裝的,所以直接配置即可。
首先,在nginx.conf檔案中的http模組下配置
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
說明:區域名稱為one(自定義),佔用空間大小為10m,平均處理的請求頻率不能超過每秒一次。
$binary_remote_addr是$remote_addr(客戶端IP)的二進位制格式,固定佔用4個位元組(可能是C語言的long型別長度)。而$remote_addr按照字串儲存,佔用7-15個位元組。這樣看來用$binary_remote_addr可以節省空間,但網上又說64位系統下都是佔用64個位元組,沒搞清楚,總之儘量用$binary_remote_addr吧。
第二,在http模組的子模組server下面配置
location ~* .htm$ { limit_req zone=one burst=5 nodelay; proxy_pass http://backend_tomcat; }
我這裡是對uri字尾為htm的請求限流,注意limit_req zone=one burst=5 nodelay;
其中zone=one和前面的定義對應。
burst這個網上都說峰值之類的,通過親自試驗發現這麼說並不準確,應該叫緩衝佇列的長度比較合適。
nodelay字面的意思是不延遲,具體說是對使用者發起的請求不做延遲處理,而是立即處理。比如我上面定義的rate=1r/s,即每秒鐘只處理1個請求。如果同一時刻有兩個字尾為htm的請求過來了,若設定了nodelay,則會立刻處理這兩個請求。若沒設定nodelay,則會嚴格執行rate=1r/s的配置,即只處理一個請求,然後下一秒鐘再處理另外一個請求。直觀的看就是頁面資料卡了,過了一秒後才加載出來。
真正對限流起作用的配置就是rate=1r/s和burst=5這兩個配置。下面我們來分析一下具體案例。
某一時刻有兩個請求同時到達nginx,其中一個被處理,另一個放到了緩衝佇列裡。雖然配置了nodelay導致第二個請求也被瞬間處理了,但還是佔用了緩衝佇列的一個長度,如果下一秒沒有請求過來,這個佔用burst一個長度的空間就會被釋放,否則就只能繼續佔用著burst的空間,直到burst空間佔用超過5之後,再來請求就會直接被nginx拒絕,返回503錯誤碼。
可見,如果第二秒又來了兩個請求,其中一個請求又佔用了一個burst空間,第三秒、第四秒直到第五秒,每秒都有兩個請求過來,雖然兩個請求都被處理了(因為配置了nodelay),但其中一個請求仍然佔用了一個burst長度,五秒後整個burst長度=5都被佔用了。第六秒再過來兩個請求,其中一個請求就被拒絕了。
這是我根據實際測試結果推論的,可能和真實的理論有所出入,但這樣講我覺得比較好理解。有清楚的朋友歡迎告知!
這裡用到的$binary_remote_addr是在客戶端和nginx之間沒有代理層的情況。如果你在nginx之前配置了CDN,那麼$binary_remote_addr的值就是CDN的IP地址。這樣限流的話就不對了。需要獲取到使用者的真實IP進行限流。
簡單說明如下:
## 這裡取得原始使用者的IP地址 map $http_x_forwarded_for $clientRealIp { "" $remote_addr; ~^(?P<firstAddr>[0-9\.]+),?.*$$firstAddr; } ## 針對原始使用者 IP 地址做限制 limit_req_zone $clientRealIp zone=one:10m rate=1r/s;
同理,我們可以用limit模組對網路爬蟲進行限流。
http模組
limit_req_zone $anti_spider zone=anti_spider:10m rate=1r/s;
server模組
location / { limit_req zone=anti_spider burst=2 nodelay; if ($http_user_agent ~* "spider|Googlebot") { set $anti_spider $http_user_agent; } }
可以用curl -I -A "Baiduspider" www.remotejob.cn/notice.jsp 測試一下
以上這篇Nginx使用limit_req_zone對同一IP訪問進行限流的方法就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。