前言
- 每次做網頁服務都不免擔心會遇到過多的流量把服務塞住;一路嘗試過幾種 ratelimit 的方式,最後決定都先取消!
- 本篇紀錄幾個常見的 ratelimit 的方式,以及為什麼我後來取消 (
發現流量不夠)。
3 種 ratelimit 的方法
方法 1:OS - iptables
|
|
Rule 說明:
-
line
2
:建立一個新的 chain 來處理 rate limit;可當作 chain 是 rules 的集合 -
line
5
:在RATE_LIMIT
這個 chain 上新增一條規則:- 「從 port
8080
、state 是NEW
的 tcp 連線,設定一個名稱API
來記錄」
- 「從 port
-
line
6
:在RATE_LIMIT
這個 chain 上再新增一條規則:- 「名稱是
API
且從 port8080
、state 是NEW
的 tcp 連線,如果在60
秒內有5
次以上的連線,則DROP
這個連線」
- 「名稱是
-
line
9
:將RATE_LIMIT
這個 chain 加到INPUT
chain 上,這樣所有進來的連線都會經過這個 rate limit 的規則
Note
-m
:(match
) 指定要使用的模組
方法 2:Nginx Configuration
|
|
其中
limit_req_zone
:定義 rate limit 的設定;可以用多個limit_req_zone
來定義不同的 rate limit$binary_remote_addr
:用來識別每個 client 的 IPzone=demo_zone:10m
:設定這個 zone:demo_zone
使用 10MB 的 shared memory zone,用來存放 rate limit 的資訊rate=5r/s
:設定 rate limit 為每秒5
個 requestlimit_req_status
:當超過 rate limit 時,返回的 status code;預設是503
,我這邊用444
代表不回應
更多設定可以參考 [2]
方法 3:你的 API 相關框架的套件
我做的服務目前都是用 Python - FastAPI
,所以可以使用 slowapi
這個套件 [3] 來做 rate limit。
例如以下是 slowapi
他們文件的範例 [4]:
|
|
假如你是用 Node.js - express
框架,可以考慮 express-rate-limit
這個套件 [5]。
最後決定移除 rate limit 設定
三種方法都做過,個人最不傾向使用 Python 的套件,怕對效能影響太大。
前兩種設定以及更新都算方便,只是我對 nginx 的設定更熟悉一些,最後都是用 nginx 的 rate limit 設定。
可是後來發現:
- ratelimit 基本上就是增加系統效能壓力,目前也沒有真的有什麼效果;甚至也可能是一種邀請 DDOS 攻擊的方式。
- 提供的服務也不是真的有超大的流量、或是重要到需要預防 DDOS 攻擊。另一方面,我做的服務要是被 DDOS 可能還是榮幸。
- 真的遇到,就花錢加買雲端服務,讓他們來幫忙處理就好。
結論是,不用特別做 ratelimit,平時做好資料備份、或研究自己架構的 auto-scaling 會比較實際。
被打爆就重啟服務、資料有損毀就還原。
REF
- https://serverfault.com/questions/340256/should-i-rate-limit-packets-with-iptables
- https://docs.nginx.com/nginx/admin-guide/security-controls/controlling-access-proxied-http/#limiting-the-request-rate
- https://github.com/laurentS/slowapi
- https://slowapi.readthedocs.io/en/latest/
- https://www.npmjs.com/package/express-rate-limit