乙個強大的軟體產品是由許多不同的元件結合完成的, 其中在每乙個產品中離不開的就是api系統, api系統在整個產品中居於中樞地位, 包括系統內部元件, 及客戶對產品的對接都要與api打交道, 這就需要最大限度的提高api的處理能力, 並且防範無效請求, 還有黑客的惡意攻擊。
限流可以在nginx層進行設定, 當然在api業務層做更加靈活、簡便, 今天就講述下flask_limiter在flask應用中的使用。
flask_limiter 是對limiter庫包裝成flask的擴充套件元件。 提供對flask訪問路徑的頻率限制。 對於其後端資料儲存有三種方式可供選擇:
1. 初始乙個limiter物件, 相關引數後續會做詳細介紹, 圖中的key_func引數是你的限制策略關鍵字, 上圖是對訪問的源ip做了限制,
在我們的業務中是針對於客戶id做了訪問限制, 這個根據業務需要自己決定, default_limits 是具體的限制策略內容也就是頻率, 這個配置是全域性配置會對flask的所有url生效
2. 在每個url的view中新增decorator, 上圖出現了兩種limiter.limit 設定限制的頻率, 此處的優先順序高於default_limits,
limiter.exempt 遮蔽限制策略。
10 per hour 以 'per' 為分隔符; 10/hour 以'/'做分隔符;10/hour;100/day;2000 per year 以『;』分隔設定多個,
100/day, 500/7days 可以新增複數
limiter.limit()
1. 單個
@limiter.limit("100/day;10/hour;1/minute")
def my_route()
2. 多個
@limiter.limit("100/day")
@limiter.limit("10/hour")
@limiter.limit("1/minute")
def my_route():
...3. 對單個url指定策略key值
def my_key_func():
[email protected]("100/day", my_key_func)
def my_route():
...
4. 動態獲取頻率限制策略(在策略需要從資料庫或者遠端api獲取的情況下使用)
def rate_limit_from_config():
@limiter.limit(rate_limit_from_config)
def my_route():
...
5. 一些特定情況下遮蔽策略(比如是超級使用者請求)
@limiter.limit("100/day", exempt_when=lambda: current_user.is_admin)
def expensive_route():
...limiter.shared_limit() 共享限制策略
1. 定義
mysql_limit = limiter.shared_limit("100/hour", scope="mysql")
@mysql_limit
def r1():
...@mysql_limit
def r2():
...
2. 動態共享限制策略(scope不指定的時候預設是endpoint_name-『%s.%s』 %(obj.__module__, obj.__name__))
def host_scope(endpoint_name):
return request.host
host_limit = limiter.shared_limit("100/hour", scope=host_scope)
@host_limit
def r1():
...@host_limit
def r2():
...
3. tip
limiter.exempt() (遮蔽策略)
limiter.request_filter()
(符合條件的遮蔽策略)
@limiter.request_filter
def header_whitelist():
return request.headers.get("x-internal", "") == "true"
@limiter.request_filter
def ip_whitelist():
return request.remote_addr == "127.0.0.1"
ratelimit_default 預設策略, 逗號分隔('1/minute,100/hour'), 只要存在其他配置會失效
ratelimit_storage_urlmemory://
orredis://host:port
ormemcached://host:port, 後端儲存資料的方式。
ratelimit_storage_options dict型別,limits.storage.storage子類, 比如 。
ratelimit_strategyfixed-window 或者
fixed-window-elastic-expiry 或者moving-window, 後續對三種模式詳細講解。
ratelimit_enabled 是否應用速率限制策略, 預設true
ratelimit_headers_enabled 是否返回速率限制的相關資訊到reponse header中預設false
ratelimit_header_limit,ratelimit_header_reset,ratelimit_header_remaining,ratelimit_header_retry_after對應配置上邊的header的鍵值字串。
ratelimit_swallow_errors 預設false即可
ratelimit_in_memory_fallback 後端儲存異常使用的策略配置
ratelimit_key_prefix 儲存key的字首配置
1.fixed-window (固定視窗)
以5/minute為例
由圖可以看出, 第一次hit到url時新增key, 類似"limiter/key_function/live_api.live_numbers/5/1/minute"的鍵值,預設值為0, 在週期內請求超過5次, 後續請求全部返回429, 第二個週期開始時key會被清除, 如此往復。
缺點:大量請求可以集中在乙個週期的結束時,及下乙個週期的開始, 黑客可以集中在這段時間攻擊系統。
2.fixed-window-elastic-expiry(固定視窗的伸展週期)
與fixed-window區別在於, 每次hit到url時key的過期時間都會延續乙個週期, 如果在達到速率限制條件時持續請求將永遠不會成功, 必須停止請求超過一週期時間, 才可以繼續請求。
3. moving-window(移動視窗)
以5/minute為例
移動視窗策略在內部維護乙個列表,當列表的長度小於5時, 就不會滿足速率限制條件, 當長度大於5時, 比如[t6, t5, t4, t3, t2, t1], 此時就會拿出t1物件, 當t1的請求時的時間戳大於等於now-expiry時拒絕請求,在t1的存在於列表中的時間大於乙個週期就會被清除。
由此可以看出此策略動態維護乙個列表, 比如如果策略為2000/minite 那這樣可能是長度為2000的列表長度維護, 相比前兩種會有更大的記憶體花銷。
與專案實踐
模型 描述業務 業務規則 系統使用 應用程式 系統架構以及系統內互動的一種視覺化方式。便於理解業務 需求,理解軟體和架構如何構造。美國前 艾森豪威爾說 計畫是零,計畫的過程是一切。模型本身並不是最重要的,建立模型的過程和經歷得思考才是最具價值。建模可以強迫你去思考,通過充分的思考,你就可以做出最好的...
真理與實踐
下面片段的摘自柴靜天涯部落格 如果真理不大寫呢 絕大多數學科都包含思辨理性 實踐理性和技藝這三種知識,但由於對知識傳統所形成的思維定勢,我們更多地把視線投向普適化的知識 大寫的真理,其他兩種的知識得不到正當化。朱蘇力說 許多人習慣了標籤式的思維,把中國基層司法實踐中的不同問題都闡釋為法治不健全 法官...
React Native 研究與實踐
github popular開發教程,原始碼解析,專案總結 react native 問題及解決方案合集 react native 效能優化 react native 每日一學 每天乙個知識點 技巧,經驗,填坑日記等 每天學一點,離大神近一點。react native 專案實踐總結 react na...