限流,顧名思義,就是限制對 api 的呼叫頻率。每一次 api 呼叫,都要花費伺服器的資源,因此很多 api 不會對使用者無限次地開放,請求達到某個次數後就不再允許訪問了,或者一段時間內,最多隻允許訪問 api 指定次數。
目前,我們的介面是沒有任何限流措施的,只要使用者呼叫介面,伺服器就會處理並返回資料。為了防止介面被惡意使用者刷爆,我們來給介面限流。
django-rest-framework 為我們提供了 2 個常用的限流功能輔助類,分別是anonratethrottle
和userratethrottle
。anonratethrottle
用於限制未認證使用者的訪問頻率,限制依據是使用者的 ip。userratethrottle
用於限定認證使用者,即**的註冊使用者(目前我們部落格不支援使用者登入註冊,所以這個類沒什麼用)。兩個類可以用於同一 api,以便對不同型別的使用者實施不同的限流政策。
這兩個輔助類限制頻率的指定格式為 "最大訪問次數/時間間隔",例如設定為10/min
,則只允許一分鐘內最多呼叫介面 10 次。超過限定次數的呼叫將丟擲exceptions.throttled
異常,客戶端收到 429 狀態碼(too many requests)的響應。
再次根據已有 api 列表和快取情況來分析一下我們的限流政策:
介面名url
限流文章列表
/api/posts/
10/min
文章詳情
/api/posts/:id/
10/min
分類列表
/categories/
10/min
標籤列表
/tags/
10/min
歸檔日期列表
/posts/archive/dates/
10/min
/api/posts/:id/comments/
10/min
文章搜尋結果
/api/search/
5/min
補充說明:
分類、標籤、歸檔日期列表,有快取,正常使用者不會訪問太頻繁,限定 10/min
搜尋介面,正常使用者不會訪問太頻繁,限定 5/min
介面限流規則制定好後,接下來就設定限流輔助類就可以了。
啟用限流有 2 種方式,一是全域性設定,二是單個檢視設定,單個檢視的設定會覆蓋全域性設定。因為幾乎所有介面都是對匿名使用者限流,因此先來進行全域性設定。在專案配置檔案 common.py 中找到rest_framework
配置項,加入如下配置:
# filename="common.py"
rest_framework =
}
這樣,所有介面訪問頻率均被設定為 10/min。
對於搜尋介面,我們制定的限流規則是 5/min,因此我們對這個檢視集的限流類進行單獨設定。
因為全域性配置中,預設設定的限流頻率為 10/min,為了將限流類的預設頻率設定為 5/min,我們需要繼承原限流類覆蓋它的throttle_rates
屬性,**非常簡單:
# filename="blog/views.py"
from rest_framework.throttling import anonratethrottle
class postsearchanonratethrottle(anonratethrottle):
throttle_rates =
接著在搜尋介面的檢視集中通過throttle_classes
指定這個限流類:
# filename="blog/views.py"
class postsearchview(haystackviewset):
index_models = [post]
serializer_class = posthaystackserializer
throttle_classes = [postsearchanonratethrottle]
我們來測試一下,限流是否真的起了作用。
一分鐘後重新訪問又恢復了正常。
再來測試一下搜尋介面,訪問 /api/v1/search/?text=markdown,在連續重新整理 5 次後,介面返回如下結果:
一分鐘後重新訪問又恢復了正常。
!!! note "注意"
因為搜尋功能依賴 elasticsearch 服務,因此測試介面時需要執行 docker 容器,可參考 基於 drf-haystack 實現文章搜尋介面。
限制介面的訪問次數
情景 傳送手機驗證碼或者郵箱驗證碼時限制規則 一分鐘只可以發一次,一天內也有次數限制。以防止惡意訪問,降低伺服器壓力。解決思路 獲取使用者ip位址,判斷此ip是否首次訪問,如果是首次訪問,在redis建立minkey,daykey.並設定minkey過期60s,daykey為86400s,也就是24...
介面限流 限制介面的訪問頻率
限流,顧名思義,就是限制對 api 的呼叫頻率。每一次 api 呼叫,都要花費伺服器的資源,因此很多 api 不會對使用者無限次地開放,請求達到某個次數後就不再允許訪問了,或者一段時間內,最多隻允許訪問 api 指定次數。目前,我們的介面是沒有任何限流措施的,只要使用者呼叫介面,伺服器就會處理並返回...
WEB INF中訪問受限制的JSP頁面的訪問方法
怎麼樣讓servlet訪問web inf下的網頁或jsp檔案呢.因為web inf下,應用伺服器把它指為禁訪目錄,即直接在瀏覽器裡是不能訪問到的.因些,可以讓servlet進行訪問,如web inf下有a.jsp則可以用request.getrequestdispatcher web inf a.j...